我正在一个新项目中使用Git,该项目有两个并行但目前处于试验阶段的开发分支:

master:导入现有的代码库,再加上一些我通常确信的修改exp1:实验分支#1exp2:实验分支#2

exp1和exp2表示两种非常不同的体系结构方法。在我进一步相处之前,我无法知道哪一个(如果有的话)会起作用。当我在一个分支中取得进展时,我有时会对另一个分支进行有用的编辑,并希望仅合并这些编辑。

将一个开发分支中的选择性更改合并到另一个分支中,同时保留其他所有内容的最佳方法是什么?

我考虑过的方法:

gitmerge——无需提交,然后手动取消大量编辑,我不想在分支之间共享这些编辑。手动将通用文件复制到临时目录中,然后git checkout移动到另一个分支,然后更多地手动将临时目录复制到工作树中。在上述基础上的变化。暂时放弃exp分支,使用另外两个本地存储库进行实验。这使得手动复制文件更加简单。

所有这三种方法都显得乏味且容易出错。我希望有更好的方法;类似于过滤器路径参数,可以使gitmerge更有选择性。


当前回答

我想要的是:在一个新的分支中,以交互方式从一个分支(它有几个混乱的提交)中选择一个大块的提交。

如果diff中有任何二进制文件,gitdiff+gitapply将无法工作。

我的方法:

# New branch from a clean starting point, e.g. master
git checkout new-clean-branch origin/master

# Get all changes from the messy branch
# (quote the star so your shell doesn't expand it)
git checkout messy-branch -- '*'

# Unstage ("un-add") everything
git restore --staged .

# Interactively add hunks to be staged for commit
git add -p

其他回答

如果您没有太多的文件被更改,这将使您没有额外的提交。

1.临时复制分支$git结帐-b temp_branch

2.重置为上次所需提交$git reset--hard HEAD~n,其中n是需要返回的提交次数

3.从原始分支签出每个文件$git签出原点/original_branch文件名.ext

现在,如果需要,您可以提交并强制推送(覆盖远程)。

1800 INFORMATION的答案完全正确。不过,作为Git的新手,“使用Git cherry pick”不足以让我在互联网上进行更多挖掘,所以我想我会发布一份更详细的指南,以防其他人也在类似的情况下。

我的用例是希望有选择地将别人的GitHub分支中的更改拉到我自己的分支中。如果您已经有一个具有更改的本地分支,则只需执行步骤2和5-7。

使用要引入的更改创建(如果未创建)本地分支。$git分支mybranch<基本分支>切换到它。$git结帐mybranch从其他人的帐户中删除所需的更改。如果还没有,则需要将它们添加为远程。$git远程添加repo-w-changes<git-url>把树枝上的东西都拔下来。$git pull-repos-w-changes-branch-i-want查看提交日志以查看所需的更改:$git日志切换回要将更改拉入的分支。$git原始付款分支Cherry用哈希一个接一个地选择你的提交。$git cherry-pick-x提交哈希

帽子提示:http://www.sourcemage.org/Git_Guide(存档副本)

我编写了自己的脚本“pmerge”来部分合并目录。这是一项正在进行的工作,我仍然在学习Git和Bash脚本。

该命令使用gitmerge--no提交,然后取消应用与提供的路径不匹配的更改。

用法:git pmerge分支路径示例:gitmerge-devel-src/

我还没有对它进行广泛的测试。工作目录应该没有任何未提交的更改和未跟踪的文件。

#!/bin/bash

E_BADARGS=65

if [ $# -ne 2 ]
then
    echo "Usage: `basename $0` branch path"
    exit $E_BADARGS
fi

git merge $1 --no-commit
IFS=$'\n'

# List of changes due to merge | replace nulls with newlines | strip lines to just filenames | ensure lines are unique
for f in $(git status --porcelain -z -uno | tr '\000' '\n' | sed -e 's/^[[:graph:]][[:space:]]\{1,\}//' | uniq); do
    [[ $f == $2* ]] && continue
    if git reset $f >/dev/null 2>&1; then
        # Reset failed... file was previously unversioned
        echo Deleting $f
        rm $f
    else
        echo Reverting $f
        git checkout -- $f >/dev/null 2>&1
    fi
done
unset IFS

最简单的方法是将存储库设置为要合并的分支,然后运行

git checkout [branch with file] [path to file you would like to merge]

如果你跑步

git status

您将看到文件已暂存。。。

然后运行

git commit -m "Merge changes on '[branch]' to [file]"

易于理解的

这并不完全是你想要的,但它对我很有用:

git checkout -p <branch> -- <paths> ...

这是一些答案的混合。