是否有 git-merge --dry-run 选项?

发布于 2024-11-15 00:41:41 字数 111 浏览 3 评论 0原文

我正在合并一个可能有很多冲突的远程分支。我怎么知道它是否会发生冲突?

我在 git-merge 上没有看到类似 --dry-run 的内容。

I'm merging in a remote branch that may have a lot of conflicts. How can I tell if it will have conflicts or not?

I don't see anything like a --dry-run on git-merge.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(21

耀眼的星火 2024-11-22 00:41:41

如前所述,传入 --no-commit 标志,但为了避免快进提交,还要传入 --no-ff,如下所示

$ git merge --no-commit --no-ff $BRANCH

:检查分阶段的更改:

$ git diff --cached

并且您可以撤消合并,即使它是快进合并:

$ git merge --abort

As noted previously, pass in the --no-commit flag, but to avoid a fast-forward commit, also pass in --no-ff, like so:

$ git merge --no-commit --no-ff $BRANCH

To examine the staged changes:

$ git diff --cached

And you can undo the merge, even if it is a fast-forward merge:

$ git merge --abort
杯别 2024-11-22 00:41:41

我只需实现一种自动查找存储库与其远程存储库之间冲突的方法。该解决方案在内存中进行合并,因此它不会触及索引,也不会触及工作树。我认为这是解决这个问题最安全的方法。它的工作原理如下:

  1. 将遥控器获取到您的存储库。例如:
    git fetch origin master
  2. 运行 git merge-base:git merge-base FETCH_HEAD master
  3. 运行 git merge-tree:git merge-tree mergebase master FETCH_HEADmergebase是上一步中merge-base打印的十六进制id)

现在假设您想要将远程master与本地master合并,但您可以使用任何分支。 git merge-tree 将在内存中执行合并并将结果打印到标准输出。 Grep 查找模式 <<>>。或者您可以将输出打印到文件中并进行检查。如果您发现以“两者均已更改”开头的行,那么很可能会发生冲突。

I just had to implement a method that automatically finds conflicts between a repository and its remote. This solution does the merge in memory so it won't touch the index, nor the working tree. I think this is the safest possible way you can solve this problem. Here's how it works:

  1. Fetch the remote to your repository. For example:
    git fetch origin master
  2. Run git merge-base: git merge-base FETCH_HEAD master
  3. Run git merge-tree: git merge-tree mergebase master FETCH_HEAD (mergebase is the hexadecimal id that merge-base printed in the previous step)

Now suppose that you want to merge the remote master with your local master, but you can use any branches. git merge-tree will execute the merge in memory and print the result to the standard output. Grep for the pattern << or >>. Or you can print the output to a file and check that. If you find a line starting with 'changed in both' then most probably there will be a conflict.

琉璃繁缕 2024-11-22 00:41:41

我假设您只是想在实际尝试合并之前找出自己遇到了多少麻烦......并且在合并失败后重置到最后一次提交相对容易,因此如果出现这种情况我不会感到惊讶是预期的方法。

也就是说,如果您确实不想触及工作树中的现有文件 - 您可以创建一个补丁并针对目标分支进行测试。这还有一个好处是可以准确显示对哪些文件进行了哪些更改 - 只需在文本编辑器中打开补丁文件即可。

git checkout -b mycrazybranch
[change some stuff...]
git add .
git commit -m "changed some stuff"
git format-patch master --stdout > crazy.patch
git checkout master
git apply crazy.patch --check
[all good! cleanup...]
rm crazy.patch

如您所见,这将创建一个补丁文件,然后您可以使用 --check 对其进行测试,看看是否有任何错误,然后删除该补丁文件。

I'm assuming you just want to find out how much trouble you're getting yourself into prior to actually attempting the merge...and resetting to the last commit after a failed merge is relatively easy so I wouldn't be surprised if that is the intended approach.

That said, if you really don't want to touch your existing files in the working tree - you could create a patch and test it against the target branch. This also has the benefit of showing exactly what changes were made to which files - just open up the patch file in a text editor.

git checkout -b mycrazybranch
[change some stuff...]
git add .
git commit -m "changed some stuff"
git format-patch master --stdout > crazy.patch
git checkout master
git apply crazy.patch --check
[all good! cleanup...]
rm crazy.patch

As you can see, this will create a patch file, you can then test it with --check and see if there are any errors, then remove the patch file.

只是我以为 2024-11-22 00:41:41

看到存在冲突后,您可以执行 git merge --abort 。

You can do git merge --abort after seeing that there are conflicts.

素罗衫 2024-11-22 00:41:41

作为现有答案的总结,有两种方法可以检查是否存在合并冲突

git format-patch $(git merge-basebranch1branch2)..branch2 --stdout | git apply --3way --check -

注意,当您运行上述命令时,当前分支应该是 branch1

另一种方式:

git merge --no-commit branch2
# check the return code here
git merge --abort

As a summary of existed answers, there are two way to check if there would be merge conflicts

git format-patch $(git merge-base branch1 branch2)..branch2 --stdout | git apply --3way --check -

Note, your current branch should be branch1 when you run above command

Another way:

git merge --no-commit branch2
# check the return code here
git merge --abort
一梦浮鱼 2024-11-22 00:41:41

我对此的简单暴力解决方案是:

  1. 创建一个“pre-master”分支(当然来自master)

  2. 合并所有您想要进入本预科课程的内容。
    然后你就可以看到合并是如何发生的,而无需接触master。

    • 将 pre-master 合并到 master 中或者
    • 将所有想要发布的分支合并到主分支

无论如何,我会遵循 @orange80 的建议。

My simple brute-force solution to this is:

  1. Create a "pre-master" branch (from master of course)

  2. Merge all the things you want to into this pre-master.
    Then you can see how the merging happened without touching master.

    • Merge pre-master into master OR
    • Merge all wannabe-released branches into master

Anyway, I would follow @orange80's advice.

丶视觉 2024-11-22 00:41:41

我为此创建了一个别名,并且工作起来就像一个魅力,我这样做:

 git config --global alias.mergetest '!f(){ git merge --no-commit --no-ff "$1"; git merge --abort; echo "Merge aborted"; };f '

现在我只是打电话

git mergetest <branchname>

来查明是否存在任何冲突。

I made an alias for doing this and works like a charm, I do this:

 git config --global alias.mergetest '!f(){ git merge --no-commit --no-ff "$1"; git merge --abort; echo "Merge aborted"; };f '

Now I just call

git mergetest <branchname>

To find out if there are any conflicts.

稀香 2024-11-22 00:41:41

撤消与 git 的合并是如此简单,您甚至不必担心试运行:

$ git pull $REMOTE $BRANCH
# uh oh, that wasn't right
$ git reset --hard ORIG_HEAD
# all is right with the world

编辑:如下面的评论所述,如果您的工作目录或暂存区域发生更改,您可能需要在执行操作之前将它们隐藏起来上面(否则它们会在上面的git重置之后消失)

Undoing a merge with git is so easy you shouldn't even worry about the dry run:

$ git pull $REMOTE $BRANCH
# uh oh, that wasn't right
$ git reset --hard ORIG_HEAD
# all is right with the world

EDIT: As noted in the comments below, if you have changes in your working directory or staging area you'll probably want to stash them before doing the above (otherwise they will disappear following the git reset above)

荒路情人 2024-11-22 00:41:41

只需将当前分支与远程分支进行比较,这将告诉您在进行拉取/合并时将会发生什么变化。

#see diff between current master and remote branch
git diff master origin/master

Just diff your current branch against the remote branch, this will tell you what is going to change when you do a pull/merge.

#see diff between current master and remote branch
git diff master origin/master
聽兲甴掵 2024-11-22 00:41:41

我很惊讶还没有人建议使用补丁。

假设您想测试从 your_branchmaster 的合并(我假设您已签出 master):

$ git diff master your_branch > your_branch.patch
$ git apply --check your_branch.patch
$ rm your_branch.patch

这应该可以做到诡计。

如果出现这样的错误,

error: patch failed: test.txt:1
error: test.txt: patch does not apply

则意味着补丁未成功,并且合并会产生冲突。没有输出意味着补丁是干净的,您可以轻松合并分支


请注意,这实际上不会更改您的工作树(当然除了创建补丁文件之外,但您可以安全地删除之后)。来自 git-apply 文档:

--check
    Instead of applying the patch, see if the patch is applicable to the
    current working tree and/or the index file and detects errors. Turns
    off "apply".

请注意比我更聪明/更有 git 经验的人:如果我在这里错了,请告诉我,并且此方法确实显示出与常规合并不同的行为。奇怪的是,在这个问题存在 8 年多的时间里,没有人会提出这个看似显而易见的解决方案。

I'm surprised nobody has suggested using patches yet.

Say you'd like to test a merge from your_branch into master (I'm assuming you have master checked out):

$ git diff master your_branch > your_branch.patch
$ git apply --check your_branch.patch
$ rm your_branch.patch

That should do the trick.

If you get errors like

error: patch failed: test.txt:1
error: test.txt: patch does not apply

that means that the patch wasn't successful and a merge would produce conflicts. No output means the patch is clean and you'd be able to easily merge the branch


Note that this will not actually change your working tree (aside from creating the patch file of course, but you can safely delete that afterwards). From the git-apply documentation:

--check
    Instead of applying the patch, see if the patch is applicable to the
    current working tree and/or the index file and detects errors. Turns
    off "apply".

Note to anyone who is smarter/more experienced with git than me: please do let me know if I'm wrong here and this method does show different behaviour than a regular merge. It seems strange that in the 8+ years that this question has existed noone would suggest this seemingly obvious solution.

○闲身 2024-11-22 00:41:41

不完全是那样。但你可以使用 --no-commit 选项,这样合并后它不会自动提交结果。通过这种方式,您可以检查并根据需要撤消合并,而不会弄乱提交树。

Not exactly like that. But you can use the --no-commit option, so it does not automatically commit the result after the merge. In this way you can inspect, and if desired, to undo the merge without messing with the commit tree.

樱花坊 2024-11-22 00:41:41

我使用 request-pull git 命令来执行此操作。它允许您查看合并时会发生的每个更改,但无需在本地或远程存储库上执行任何操作

例如,假设您想要将一个名为“feature-x”的分支合并到您的 master 分支中,

git request-pull master origin feature-x

则会向您显示将发生的情况的摘要(不执行任何操作):

The following changes since commit fc01dde318:
    Layout updates (2015-06-25 11:00:47 +0200)
are available in the git repository at:
    http://fakeurl.com/myrepo.git/ feature-x
for you to fetch changes up to 841d3b41ad:
----------------------------------------------------------------
john (2):
    Adding some layout
    Refactoring
ioserver.js            |   8 +++---
package.json           |   7 +++++-
server.js              |   4 +--
layout/ldkdsd.js       | 277 +++++++++++++++++++++++++++++++++++++
4 files changed, 289 insertions(+), 7 deletions(-)
create mode 100644 layout/ldkdsd.js

如果添加 -p 参数,您还将获得完整的补丁文本,就像您对每个更改的文件执行 git diff 一样。

I use the request-pull git command to do so. It allows you to see every change that would happen when merging, but without doing anything on your local or remote repositories.

For instance, imagine you want to merge a branch named "feature-x" into your master branch

git request-pull master origin feature-x

will show you a summary of what would happen (without doing anything):

The following changes since commit fc01dde318:
    Layout updates (2015-06-25 11:00:47 +0200)
are available in the git repository at:
    http://fakeurl.com/myrepo.git/ feature-x
for you to fetch changes up to 841d3b41ad:
----------------------------------------------------------------
john (2):
    Adding some layout
    Refactoring
ioserver.js            |   8 +++---
package.json           |   7 +++++-
server.js              |   4 +--
layout/ldkdsd.js       | 277 +++++++++++++++++++++++++++++++++++++
4 files changed, 289 insertions(+), 7 deletions(-)
create mode 100644 layout/ldkdsd.js

If you add the -pparameter, you will also get the full patch text, exactly like if you were doing a git diff on every changed file.

各自安好 2024-11-22 00:41:41

Git 在合并时引入了 --ff-only 选项。

来自:http://git-scm.com/docs/git-merge

<小时>

--仅限 ff

<块引用>

拒绝合并并以非零状态退出,除非当前 HEAD 已经是最新的或者可以将合并解析为快进。

这样做将尝试合并和快进,如果不能,它会中止并提示您无法执行快进,但保持您的工作分支不变。如果它可以快进,那么它将在您的工作分支上执行合并。此选项也可在 git pull 上使用。因此,您可以执行以下操作:

git pull --ff-only origin branchA #See if you can pull down and merge branchA

git merge --ff-only branchA branchB #See if you can merge branchA into branchB

Git introduced a --ff-only option when merging.

From: http://git-scm.com/docs/git-merge


--ff-only

Refuse to merge and exit with a non-zero status unless the current HEAD is already up-to-date or the merge can be resolved as a fast-forward.

Doing this will attempt to merge and fast-forward, and if it can't it aborts and prompts you that the fast-forward could not be performed, but leaves your working branch untouched. If it can fast-forward, then it will perform the merge on your working branch. This option is also available on git pull. Thus, you could do the following:

git pull --ff-only origin branchA #See if you can pull down and merge branchA

git merge --ff-only branchA branchB #See if you can merge branchA into branchB
悲念泪 2024-11-22 00:41:41

这可能很有趣:来自文档:

如果您尝试合并导致复杂的冲突并且想要
重新开始,您可以使用 git merge --abort 恢复。

但您也可以采用简单(但缓慢)的方式:(

rm -Rf /tmp/repository
cp -r repository /tmp/
cd /tmp/repository
git merge ...
...if successful, do the real merge. :)

注意:仅克隆到 /tmp 是行不通的,您需要一个副本,以确保未提交的更改不会发生冲突)。

This might be interesting: From the documentation:

If you tried a merge which resulted in complex conflicts and want to
start over, you can recover with git merge --abort.

But you could also do it the naive (but slow) way:

rm -Rf /tmp/repository
cp -r repository /tmp/
cd /tmp/repository
git merge ...
...if successful, do the real merge. :)

(Note: It won't work just cloning to /tmp, you'd need a copy, in order to be sure that uncommitted changes will not conflict).

爱你是孤单的心事 2024-11-22 00:41:41

我使用 git log 查看 master 分支的功能分支上发生了什么变化,

git log does_this_branch..contain_this_branch_changes

例如- 查看已/未合并到 master 的功能分支中有哪些提交:

git log master..feature_branch

I use git log to see what has changed on a feature branch from master branch

git log does_this_branch..contain_this_branch_changes

e.g. - to see what commits are in a feature branch that has/not been merged to master:

git log master..feature_branch
掩于岁月 2024-11-22 00:41:41

我的解决方案是向后合并。

不要将您的分支合并到远程“目标”分支,而是将该分支合并到您的分支中。

git checkout my-branch
git merge origin/target-branch

您将了解是否存在任何冲突,并可以计划如何解决它们。

之后,您可以通过 git merge --abort 中止合并,或者(如果没有任何冲突并且发生合并)通过 git reset --hard 回滚到之前的提交头~1

My solution is to merge backwards.

Instead of merging your branch into the remote "target" branch, merge that branch into yours.

git checkout my-branch
git merge origin/target-branch

You will see if there are any conflicts and can plan on how to solve them.

After that you can either abort the merge via git merge --abort, or (if there weren't any conflicts and merge has happened) roll back to previous commit via git reset --hard HEAD~1

江南烟雨〆相思醉 2024-11-22 00:41:41

我只想查看冲突(目前还无法使用 GitHub 中的 diff3 查看冲突)。充分利用上面的答案,我想出了这个:

git merge --no-commit --no-ff @{upstream}
git grep -l '<<<<<<< HEAD' | xargs -I % sh -c "echo -e '\n\e[93m%\n---\e[0m' && cat %"
git merge --abort

对我来说,这是为了检查我的 PR。您可以将 @{upstream} 替换为任何分支。

我希望这对某人有帮助。

I want to see just the conflicts (can't see them with diff3 in GitHub, yet). Leveraging heavily from this answer above, I came up with this:

git merge --no-commit --no-ff @{upstream}
git grep -l '<<<<<<< HEAD' | xargs -I % sh -c "echo -e '\n\e[93m%\n---\e[0m' && cat %"
git merge --abort

For me, this is for checking my PRs. You can substitute @{upstream} with whatever branch.

I hope that's helpful to someone.

落墨 2024-11-22 00:41:41

如果你想从 B 快进到 A,那么你必须确保 git log B..A 没有向你显示任何内容,即 A 没有 B 没有的东西。但即使 B..A 有东西,你仍然可以在没有冲突的情况下合并,所以上面显示了两件事:将会有一个快进,因此你不会发生冲突。

If you want to fast forward from B to A, then you must make sure that git log B..A shows you nothing, i.e. A has nothing that B doesn't have. But even if B..A has something, you might still be able to merge without conflicts, so the above shows two things: that there will be a fast-forward, and thus you won't get a conflict.

爱情眠于流年 2024-11-22 00:41:41

我知道这在理论上是偏离主题的,但对于通过谷歌搜索登陆这里的人来说实际上非常切题。

如有疑问,您可以随时使用 Github 界面创建拉取请求,并检查它是否表明可以进行干净合并。

I know this is theoretically off-topic, but practically very on-topic for people landing here from a Google search.

When in doubt, you can always use the Github interface to create a pull-request and check if it indicates a clean merge is possible.

花之痕靓丽 2024-11-22 00:41:41

另一种选择是进行“虚拟”合并并轻松查看合并结果,包括冲突:

# Define the branches
origin_branch="$(git rev-parse --abbrev-ref HEAD)" #get current checked out branch
destination_branch="origin/main"

# Perform the merge-tree command (virtual merge)
git merge-tree --write-tree $origin_branch $destination_branch

如果您只想查看冲突,可以按如下方式修改上面的脚本:

# Define the branches
origin_branch="$(git rev-parse --abbrev-ref HEAD)" #get current checked out branch
destination_branch="origin/main"

# Perform the merge-tree command and capture the output
merge_output=$(git merge-tree --write-tree --name-only $origin_branch $destination_branch)

# Extract file names with conflicts from the merge output using grep and store in an array
mapfile -t conflicted_files < <(echo "$merge_output" | grep -E '^CONFLICT*' | awk '{print $NF}')

# Display the list of file conflicts
echo "Conflicts found in the following files:"
printf '%s\n' "${conflicted_files[@]}"

Another option would be to do a "virtual" merge and easily see the result of the merge, including conflicts:

# Define the branches
origin_branch="$(git rev-parse --abbrev-ref HEAD)" #get current checked out branch
destination_branch="origin/main"

# Perform the merge-tree command (virtual merge)
git merge-tree --write-tree $origin_branch $destination_branch

And if you want to see only the conflicts, you can modify the script above as follows:

# Define the branches
origin_branch="$(git rev-parse --abbrev-ref HEAD)" #get current checked out branch
destination_branch="origin/main"

# Perform the merge-tree command and capture the output
merge_output=$(git merge-tree --write-tree --name-only $origin_branch $destination_branch)

# Extract file names with conflicts from the merge output using grep and store in an array
mapfile -t conflicted_files < <(echo "$merge_output" | grep -E '^CONFLICT*' | awk '{print $NF}')

# Display the list of file conflicts
echo "Conflicts found in the following files:"
printf '%s\n' "${conflicted_files[@]}"
乖乖兔^ω^ 2024-11-22 00:41:41

制作工作副本的临时副本,然后合并到其中,并对两者进行比较。

Make a temporary copy of your working copy, then merge into that, and diff the two.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文