我在一个新项目上使用git,该项目有两个并行 - 但目前是实验性的 - 开发分支:
master
:导入现有的代码库加上一些我一般都知道的modexp1
:实验分支#1exp2
:实验分支#2exp1
和exp2
代表两种截然不同的建筑方法。直到我走得更远,我无法知道哪一个(如果有的话)会起作用。当我在一个分支中取得进展时,我有时会在另一个分支中进行编辑,并且只想合并那些。
将选择性更改从一个开发分支合并到另一个开发分支而将其他所有内容合并的最佳方法是什么?
我考虑过的方法:
git merge --no-commit
随后手动取消大量编辑,我不想在分支之间做出共同点。git checkout
移动到另一个分支,然后手动将临时目录复制到工作树中。exp
分支,并使用另外两个本地存储库进行实验。这使得手动复制文件更加简单。所有这三种方法都显得乏味且容易出错。我希望有更好的方法;类似于过滤器路径参数的东西会使git-merge
更具选择性。
这不完全是你想要的,但它对我有用:
git checkout --patch <branch> <file path>
这是一些答案的混合。
我有与上面提到的完全相同的问题。但我发现[alias]
在解释答案时更清楚。
来自以上链接的命令:
.gitconfig
我会做的
git diff commit1..commit2 filepattern | git-apply --index && git commit
这样,您可以限制来自分支的文件模式的提交范围。
被盗:.git/config
我喜欢上面的'git-interactive-merge'答案,但有一个更简单。让git使用交互式的rebase组合为你做这个:
[alias]
mergetool-file = "!sh -c 'git show $1:$2 > $2.theirs; git show $(git merge-base $1 $(git rev-parse HEAD)):$2 > $2.base; /C/BCompare3/BCompare.exe $2.theirs $2 $2.base $2; rm -f $2.theirs; rm -f $2.base;' -"
所以情况是你想要来自'feature'分支的C1和C2(分支点'A'),但现在不需要其余的。
[alias]
mergetool-file = "!sh -c 'git show $1:$2 > $2.theirs; git show $(git merge-base $1 $(git rev-parse HEAD)):$2 > $2.base; git merge-file $2 $2.base $2.theirs; rm -f $2.theirs; rm -f $2.base;' -"
如上所述,您将进入交互式编辑器,在该编辑器中为C1和C2选择“拾取”行(如上所述)。保存并退出,然后它将继续使用rebase并给你分支'temp'和HEAD在master + C1 + C2:
git mergetool-file <source branch> <file path>
然后你可以将master更新为HEAD并删除temp分支,你很高兴:
git checkout -p <branch> -- <paths> ...
我知道这个问题很老,还有很多其他答案,但是我编写了自己的脚本'pmerge'来部分合并目录。这是一项正在进行的工作,我仍在学习git和bash脚本。
此命令使用this git blog,然后取消应用与提供的路径不匹配的更改。
用法:#You are in the branch you want to merge to
git checkout <branch_you_want_to_merge_from> <file_paths...>
示例:http://www.gelato.unsw.edu.au/archives/git/0701/37964.html
我没有广泛测试过它。工作目录应该没有任何未提交的更改和未跟踪的文件。
A---C1---o---C2---o---o feature
/
----o---o---o---o master
怎么样# git branch temp feature
# git checkout master
# git rebase -i --onto HEAD A temp
?我很惊讶没人提到它。
对我来说,这是从另一个分支中选择性地选择更改的最简单方法,因为,此命令放入我的工作树,所有差异更改,我可以轻松选择或还原我需要的那个。通过这种方式,我可以完全控制提交的文件。
您可以使用 A---C1---o---C2---o---o feature
/
----o---o---o---o-master--C1---C2 [HEAD, temp]
将给定的远程树读取或合并到当前索引中,例如:
# git branch -f master HEAD
# git branch -d temp
要执行合并,请改用git merge --no-commit
。
另见:git pmerge branch path
一种通过文件选择性合并/提交的简单方法:
git merge develop src/
如果您没有太多已更改的文件,这将使您无需额外提交。
1.暂时重复分支
#!/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 w 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
2.重置为上次想要的提交
git reset --soft branch
,其中read-tree
是你需要返回的提交数量
3.从原始分支签出每个文件
git remote add foo [email protected]/foo.git
git fetch foo
git read-tree --prefix=my-folder/ -u foo/master:trunk/their-folder
现在,如果需要,您可以提交并强制推送(覆盖远程)。
当两个分支的当前提交之间只有少数文件发生变化时,我通过浏览不同的文件来手动合并更改。
-m
如果你只需要合并一个特定的目录,并保留其他所有内容并保留历史记录,你可以试试这个...在你实验之前创建一个新的How do I merge a sub directory in git?离开
git checkout dstBranch
git merge srcBranch
// make changes, including resolving conflicts to single files
git add singleFile1 singleFile2
git commit -m "message specific to a few files"
git reset --hard # blow away uncommitted changes
。
以下步骤假设您有两个分支$ git checkout -b temp_branch
和$ git reset --hard HEAD~n
,并且您要合并的目录n
位于$ git checkout origin/original_branch filename.ext
中。还假设您在目标中有其他目录,如git difftoll <branch-1>..<branch-2>
,您不想更改并保留历史记录。此外,假设target-branch
中存在合并冲突。
master