我有一个 git 分支(例如主线),我想合并到另一个开发分支。还是我?
为了决定我是否真的想合并这个分支,我想看看合并将做什么的某种预览。最好能够查看正在应用的提交列表。
到目前为止,我能想到的最好的方法是 merge --no-ff --no-commit
,然后是 diff HEAD
。
git merge
和 git reset --keep HEAD@{1}
。
git reset --keep HEAD@{1}
返回了 fatal: Cannot do a keep reset in the middle of a merge.
帮助?
--preview
选项?
git log ..otherbranch 将合并到当前分支的更改列表。
将合并到当前分支的更改列表。
git diff ...otherbranch 从共同祖先(合并基础)到将要合并的内容的头部的差异。请注意三个点,与两个点相比,它们具有特殊的含义(见下文)。
从共同祖先(合并基础)到将要合并的内容的头部的差异。请注意三个点,与两个点相比,它们具有特殊的含义(见下文)。
gitk ...otherbranch 自上次合并以来分支的图形表示。
自上次合并以来分支的图形表示。
空字符串意味着 HEAD
,所以这就是为什么只使用 ..otherbranch
而不是 HEAD..otherbranch
。
两个点与三个点对于 diff 的含义与列出修订的命令(log、gitk 等)的含义略有不同。对于 log 和其他,两个点 (a..b
) 表示在 b
但不在 a
中的所有内容,三个点 (a...b
) 表示仅在 a
或 b
之一中的所有内容。但是 diff 适用于两个修订版本,并且由两个点 (a..b
) 表示的更简单的情况是从 a
到 b
的简单差异,三个点 (a...b
) 表示共同祖先和 b
之间的差异 ({ 12})。
我发现最适合我的解决方案是执行合并并在发生冲突时中止它。这种特殊的语法对我来说感觉干净简单。这是下面的策略2。
但是,如果您想确保不会弄乱当前的分支,或者无论是否存在冲突,您都还没有准备好合并,只需创建一个新的子分支并将其合并:
策略1:安全的方式——合并一个临时分支:
git checkout mybranch
git checkout -b mynew-temporary-branch
git merge some-other-branch
这样,如果您只想查看冲突是什么,您可以简单地丢弃临时分支。您无需费心“中止”合并,您可以回到您的工作 - 只需再次签出“mybranch”,您的分支中不会有任何合并代码或合并冲突。
这基本上是一个试运行。
策略 2:当你确定要合并时,但前提是没有冲突
git checkout mybranch
git merge some-other-branch
如果 git 报告冲突(并且仅当存在冲突时),您可以执行以下操作:
git merge --abort
如果合并成功,则不能中止它(只能重置)。
如果您还没有准备好合并,请使用上述更安全的方法。
[编辑:2016 年 11 月 - 我将策略 1 换成 2,因为似乎大多数人都在寻找“安全的方式”。策略 2 现在更像是一个说明,如果合并存在您尚未准备好处理的冲突,您可以简单地中止合并。请记住,如果阅读评论!]
git merge --no-ff --no-commit
。这消除了对不同分支的“需求”,使得审查更改变得更容易,imo。
git merge --abort
?即使合并不会产生冲突?
git reset --hard HEAD
中中止合并,然后签出不同的分支 git checkout <different branch name>
并删除临时分支 git delete -b <name of temporary branch>
。
这里的大多数答案要么需要一个干净的工作目录和多个交互式步骤(不利于脚本编写),要么不适用于所有情况,例如过去的合并已经将一些未完成的更改带入您的目标分支,或者樱桃挑选做相同的。
要真正了解如果将 develop
合并到 master
分支中会发生什么变化,现在:
git merge-tree $(git merge-base master develop) master develop
由于它是一个管道命令,它不会猜测您的意思,您必须明确。它也不会为输出着色或使用您的寻呼机,因此完整的命令将是:
git merge-tree $(git merge-base master develop) master develop | colordiff | less -R
— https://git.seveas.net/previewing-a-merge-result.html
(感谢大卫诺明顿的链接)
PS:
如果您遇到合并冲突,它们将在输出中显示常见的冲突标记,例如:
$ git merge-tree $(git merge-base a b ) a b
added in both
our 100644 78981922613b2afb6025042ff6bd878ac1994e85 a
their 100644 61780798228d17af2d34fce4cfbdf35556832472 a
@@ -1 +1,5 @@
+<<<<<<< .our
a
+=======
+b
+>>>>>>> .their
用户@dreftymac 提出了一个很好的观点:这使得它不适合编写脚本,因为你不能轻易地从状态代码中捕捉到它。冲突标记可能会因情况而异(删除与修改等),这也使得 grep 变得困难。谨防。
true
,如果没有冲突,则返回 false
(例如,不需要“眼球”测试或任何人工干预的布尔值)。
git merge-tree ... | grep -q '^[a-z].*in both$' && echo conflict || echo safe to merge
之类的东西,但它是 finnicky;我可能忘记了一个案例。也许您想检查冲突标记,而不是?例如,这可能不会捕获“他们的已删除,我们的已更改”的样式冲突。 (我刚刚检查过,它甚至没有显示冲突标记,所以你需要一个细致的正则表达式才能在这里安全)
less -R
处理彩色输出而不修改您的配置。
如果您像我一样,您正在寻找等同于 svn update -n
的东西。以下似乎可以解决问题。请注意,请务必先执行 git fetch
,以便您的本地存储库具有适当的更新以进行比较。
$ git fetch origin
$ git diff --name-status origin/master
D TableAudit/Step0_DeleteOldFiles.sh
D TableAudit/Step1_PopulateRawTableList.sh
A manbuild/staff_companies.sql
M update-all-slave-dbs.sh
或者如果你想要从你的头到遥控器的差异:
$ git fetch origin
$ git diff origin/master
与建议“合并然后中止”的顶级解决方案相比,IMO 这个解决方案更容易且更不容易出错(因此风险也更小)。
$ git checkout target-branch
,然后是 $ git diff --name-status ...branch-to-be-merged
(三个点是必不可少的,所以按原样输入)
如果您已经获取了更改,我最喜欢的是:
git log ...@{u}
我相信这需要 git 1.7.x。 @{u}
表示法是上游分支的“简写”,因此它比 git log ...origin/master
更加通用。
注意:如果您使用 zsh 和扩展的 glog 东西,您可能必须执行以下操作:
git log ...@\{u\}
添加到现有答案中,可以创建一个别名以在合并之前显示差异和/或日志。许多答案省略了在“预览”合并之前首先完成的 fetch
;这是将这两个步骤合二为一的别名(模拟类似于 mercurial 的 hg incoming
/ outgoing
的东西)
因此,在“git log ..otherbranch
”的基础上,您可以将以下内容添加到 ~/.gitconfig
:
...
[alias]
# fetch and show what would be merged (use option "-p" to see patch)
incoming = "!git remote update -p; git log ..@{u}"
为了对称,以下别名可用于显示在推送之前已提交和将要推送的内容:
# what would be pushed (currently committed)
outgoing = log @{u}..
然后你可以运行“git incoming
”来显示很多变化,或者“git incoming -p
”来显示补丁(即“差异”),“git incoming --pretty=oneline
”,以获得简洁的摘要等。你然后可以(可选地)运行“git pull
”来实际合并。 (不过,既然您已经提取了,可以直接进行合并。)
同样,“git outgoing
”显示了如果您要运行“git push
”将推送的内容。
如果您进行合并,git log currentbranch..otherbranch
将为您提供将进入当前分支的提交列表。提供有关提交详细信息的 log 通常参数将为您提供更多信息。
git diff currentbranch otherbranch
将为您提供将成为一个的两个提交之间的差异。这将是一个差异,为您提供将要合并的所有内容。
这些会有帮助吗?
git log otherbranch..currentbranch
给出了 currentbranch 上的提交列表。 git diff otherbranch currentbranch
为您提供了从待合并版本到当前提示的差异,这几乎是无用的,因为您想要的是从合并基础到合并头的差异。
没有以一种丢弃的方式实际执行合并(参见 Kasapo 的回答),似乎没有一种可靠的方式来看待这一点。
话虽如此,这是一种稍微接近的方法:
git log TARGET_BRANCH...SOURCE_BRANCH --cherry
这可以公平地表明哪些提交将进入合并。要查看差异,请添加 -p
。要查看文件名,请添加 --raw
、--stat
、--name-only
、--name-status
中的任何一个。
git diff TARGET_BRANCH...SOURCE_BRANCH
方法的问题(请参阅 Jan Hudec 的回答)是,如果您的源分支包含交叉合并,您将看到目标分支中已有更改的差异。
拉取请求 - 我已经使用了大部分已经提交的想法,但我也经常使用的一个是(特别是如果它来自另一个开发者)做一个拉取请求,它提供了一种方便的方法来审查合并中的所有更改,然后再进行地方。我知道那是 GitHub 而不是 git,但它确实很方便。
也许这可以帮助你? git-diff-tree - 比较通过两个树对象找到的 blob 的内容和模式
我不想使用 git merge 命令作为查看冲突文件的前导。我不想进行合并,我想在合并之前找出潜在的问题——自动合并可能对我隐藏的问题。我一直在寻找的解决方案是如何让 git 吐出两个分支中已更改的文件列表,这些文件将在未来合并在一起,相对于某个共同的祖先。一旦我有了那个列表,我就可以使用其他文件比较工具来进一步查找。我已经搜索了多次,但我仍然没有在本机 git 命令中找到我想要的内容。
这是我的解决方法,以防它帮助其他人:
在这种情况下,我有一个名为 QA 的分支,自上次生产版本以来,它发生了许多变化。我们最后的生产版本标记为“15.20.1”。我有另一个名为 new_stuff 的开发分支,我想将它合并到 QA 分支中。 QA 和 new_stuff 都指向“遵循”(由 gitk 报告)15.20.1 标签的提交。
git checkout QA
git pull
git diff 15.20.1 --name-only > QA_files
git checkout new_stuff
git pull
git diff 15.20.1 --name-only > new_stuff_files
comm -12 QA_files new_stuff_files
以下是一些关于为什么我对针对这些特定文件感兴趣的讨论:
https://softwareengineering.stackexchange.com/questions/199780/how-far-do-you-trust-automerge
我试过这个东西来查看 Visual Studio 代码的变化。
从 dev 创建一个临时分支。然后将更改文件的分支与 --no-ff --no-commit 标志合并。
git checkout dev
git checkout -b feature_temp
git merge feature --no-ff --no-commit
功能分支的更改文件将反映在 feature_temp 分支中。
不定期副业成功案例分享
git checkout master
。我想知道为什么它说我所有的更改都会被覆盖......git show ..otherbranch
将显示将合并到当前分支的更改和差异列表。