如何在git分支之间找到更改的公共文件?

时间:2021-08-05 07:25:56

I have an upstream repository with some changes. I have local changes I want to rebase onto the upstream changes. I want to know what files I've changed locally have also changed upstream so I can check any automatic merging. Alternatively, I'd like to manually do any merges during the rebase.

我有一个上游存储库,有一些变化。我有本地更改,我想改变上游的变化。我想知道我在本地更改的文件也改变了上游,所以我可以检查任何自动合并。或者,我想在rebase期间手动执行任何合并。

4 个解决方案

#1


Expanded a bit: for you first part of the question, make a new branch, automatically do the rebase there, and then compare to your working copy.

稍微扩展一下:对于你的第一部分问题,创建一个新分支,自动在那里进行rebase,然后与你的工作副本进行比较。

git branch workBranch
git commit #throw your locals into your own branch for a brief moment
git branch testBranch
git rebase otherBranch
git diff workBranch

You might also get away with just doing a "git diff origin/branchToMerge"

你可能也只是做了一个“git diff origin / branchToMerge”

For the interactive part:

对于交互式部分:

git rebase --interactive.

Set all the commits to "Edit" and you'll be taken through each of them one-by-one giving you a chance to see everything done for that commit and edit to your heart's content.

将所有提交设置为“编辑”,您将逐个完成每个提交,让您有机会查看为该提交完成的所有操作并编辑您的内容。

EDIT to answer comment

编辑回答评论

OK, for strictly seeing changed files, do:

好的,为了严格查看更改的文件,请执行:

git log a0a0a0..b1b1b1 --name-only --pretty=oneline | egrep -v '^[a-f0-9]{40} ' | sort | uniq > lista
git log a0a0a0..c2c2c2 --name-only --pretty=oneline | egrep -v '^[a-f0-9]{40} ' | sort | uniq > listb
cat lista listb | sort | uniq -d

That bit of shell kludgery will show you only files that changed in both logs. For a0a0a0, use your common point. Replace the b1/c2 strings with the tips of the two diverging branches.

那些shell kludgery只显示两个日志中都有变化的文件。对于a0a0a0,请使用您的共同点。用两个发散分支的尖端替换b1 / c2弦。

#2


Listing changed files

Since a rebase/merge can be time-consuming, it's best to avoid doing an unnecessary one. There are a variety of ways to see what's been changed, depending on what sort of information you need.

因为rebase / merge可能很耗时,所以最好避免做一个不必要的。根据您需要的信息类型,有多种方法可以查看已更改的内容。

If you're interested in knowing per commit what files have changed, I'd suggest git-log:

如果你有兴趣了解每次提交哪些文件已更改,我建议使用git-log:

git log [--pretty=<format>] --name-only <common-branch>..<local-branch>

You can use the --pretty option to get the header information you need; <format> can be a variety of choices, including a custom string with fields - see the man page for more information.

您可以使用--pretty选项获取所需的标头信息; 可以有多种选择,包括带字段的自定义字符串 - 有关详细信息,请参阅手册页。

The --name-only option is actually being passed through to git-diff, so if you don't care about per-commit results, you can go straight to the source:

--name-only选项实际上是传递给git-diff,所以如果你不关心每次提交结果,你可以直接找到源:

git diff --name-only <common-branch> <local-branch>

Note that the branches are specified differently for the two commands.

请注意,两个命令的分支指定方式不同。

You can apply this to the upstream changes as well, changing <local-branch> to <upstream-branch>, and end up with two lists of files. I'll leave it up to you to figure out how you want to compare them, though the -f option of grep can be handy...

您也可以将此应用于上游更改,将 更改为 ,最后得到两个文件列表。我会告诉你如何比较它们,虽然grep的-f选项可以很方便...

Manual merges

Autocracy beat me to this. If you've done some smart processing based on output of git-log you could edit only the commits you saw had overlapping file changes. If you were merging rather than rebasing, you'd use the --no-commit option.

专制统治打败了我。如果您已经根据git-log的输出完成了一些智能处理,则只能编辑您看到的重叠文件更改的提交。如果您要合并而不是重新定位,则使用--no-commit选项。

See also the configuration section of the git-merge man page. You might want to set merge.conflictstyle to diff3, so that you can see the original text as well as the changes on either side.

另请参阅git-merge手册页的配置部分。您可能希望将merge.conflictstyle设置为diff3,以便您可以查看原始文本以及任何一方的更改。

If you're really desperate to suppress all attempts at automatic conflict resolution, I believe you could plug in a dummy mergetool (via merge.tool and mergetool.cmd) that does nothing and returns failure.

如果你真的急于压制所有自动冲突解决的尝试,我相信你可以插入一个虚拟的合并工具(通过merge.tool和mergetool.cmd),什么都不做并返回失败。

Having said all of this, I should also say that in my experience with git merges, I have seen plenty of conflicts but cannot remember a single incorrect automatic merge. I personally trust it's merging capabilities. Checking up on it after should really be plenty.

说完所有这些后,我还应该说,根据我对git merge的经验,我看到了很多冲突,但是记不起一次不正确的自动合并。我个人相信它的合并能力。之后检查它应该是充足的。

#3


I know this is a really old topic, but we found that git diff --name-only was returning too many false positive modified files if the two branches are too differents. Here's what we use at work to perform review code for commits of a new branch against our feature branch (possibly already partially merged in the feature branch).

我知道这是一个非常古老的话题,但是我们发现git diff --name-only返回了太多的误报修改文件,如果这两个分支太不同了。这是我们在工作中使用的功能,用于针对我们的功能分支执行新分支的提交的审阅代码(可能已经在功能分支中部分合并)。

being in our new_branch and under *nix system we use this command:

在我们的new_branch和* nix系统下,我们使用这个命令:

git show --name-only $( git cherry -v feature_branch | grep '^+' | awk '{ print($2) }' ) | egrep -v '^(commit |Author:|Date:|\s|$)' | sort -u

replacing feature_branch by the name of the branch you want to check modified files against.

将feature_branch替换为要检查修改文件的分支的名称。

The advantages of this techniques is that it really sorts only files modified by commits that belong to your branch and that are not already merged in your feature_branch.

这种技术的优点是它实际上只对由属于您的分支的提交修改的文件进行排序,并且这些文件尚未在您的feature_branch中合并。

If you want to check between two commits SHA1 and SHA2 you also can do:

如果要在两个提交SHA1和SHA2之间进行检查,您还可以执行以下操作:

git show --name-only $( git cherry -v SHA1 SHA2 | grep '^+' | awk '{ print($2) }' ) | egrep -v '^(commit |Author:|Date:|\s|$)' | sort -u

#4


this will list the top 20 files of your branch which has changed most frequently

这将列出最常更改的分支的前20个文件

git log --pretty=format: --name-only | sort | uniq -c | sort -rg | head -20

git log --pretty = format: - name-only |排序| uniq -c | sort -rg |头-20

#1


Expanded a bit: for you first part of the question, make a new branch, automatically do the rebase there, and then compare to your working copy.

稍微扩展一下:对于你的第一部分问题,创建一个新分支,自动在那里进行rebase,然后与你的工作副本进行比较。

git branch workBranch
git commit #throw your locals into your own branch for a brief moment
git branch testBranch
git rebase otherBranch
git diff workBranch

You might also get away with just doing a "git diff origin/branchToMerge"

你可能也只是做了一个“git diff origin / branchToMerge”

For the interactive part:

对于交互式部分:

git rebase --interactive.

Set all the commits to "Edit" and you'll be taken through each of them one-by-one giving you a chance to see everything done for that commit and edit to your heart's content.

将所有提交设置为“编辑”,您将逐个完成每个提交,让您有机会查看为该提交完成的所有操作并编辑您的内容。

EDIT to answer comment

编辑回答评论

OK, for strictly seeing changed files, do:

好的,为了严格查看更改的文件,请执行:

git log a0a0a0..b1b1b1 --name-only --pretty=oneline | egrep -v '^[a-f0-9]{40} ' | sort | uniq > lista
git log a0a0a0..c2c2c2 --name-only --pretty=oneline | egrep -v '^[a-f0-9]{40} ' | sort | uniq > listb
cat lista listb | sort | uniq -d

That bit of shell kludgery will show you only files that changed in both logs. For a0a0a0, use your common point. Replace the b1/c2 strings with the tips of the two diverging branches.

那些shell kludgery只显示两个日志中都有变化的文件。对于a0a0a0,请使用您的共同点。用两个发散分支的尖端替换b1 / c2弦。

#2


Listing changed files

Since a rebase/merge can be time-consuming, it's best to avoid doing an unnecessary one. There are a variety of ways to see what's been changed, depending on what sort of information you need.

因为rebase / merge可能很耗时,所以最好避免做一个不必要的。根据您需要的信息类型,有多种方法可以查看已更改的内容。

If you're interested in knowing per commit what files have changed, I'd suggest git-log:

如果你有兴趣了解每次提交哪些文件已更改,我建议使用git-log:

git log [--pretty=<format>] --name-only <common-branch>..<local-branch>

You can use the --pretty option to get the header information you need; <format> can be a variety of choices, including a custom string with fields - see the man page for more information.

您可以使用--pretty选项获取所需的标头信息; 可以有多种选择,包括带字段的自定义字符串 - 有关详细信息,请参阅手册页。

The --name-only option is actually being passed through to git-diff, so if you don't care about per-commit results, you can go straight to the source:

--name-only选项实际上是传递给git-diff,所以如果你不关心每次提交结果,你可以直接找到源:

git diff --name-only <common-branch> <local-branch>

Note that the branches are specified differently for the two commands.

请注意,两个命令的分支指定方式不同。

You can apply this to the upstream changes as well, changing <local-branch> to <upstream-branch>, and end up with two lists of files. I'll leave it up to you to figure out how you want to compare them, though the -f option of grep can be handy...

您也可以将此应用于上游更改,将 更改为 ,最后得到两个文件列表。我会告诉你如何比较它们,虽然grep的-f选项可以很方便...

Manual merges

Autocracy beat me to this. If you've done some smart processing based on output of git-log you could edit only the commits you saw had overlapping file changes. If you were merging rather than rebasing, you'd use the --no-commit option.

专制统治打败了我。如果您已经根据git-log的输出完成了一些智能处理,则只能编辑您看到的重叠文件更改的提交。如果您要合并而不是重新定位,则使用--no-commit选项。

See also the configuration section of the git-merge man page. You might want to set merge.conflictstyle to diff3, so that you can see the original text as well as the changes on either side.

另请参阅git-merge手册页的配置部分。您可能希望将merge.conflictstyle设置为diff3,以便您可以查看原始文本以及任何一方的更改。

If you're really desperate to suppress all attempts at automatic conflict resolution, I believe you could plug in a dummy mergetool (via merge.tool and mergetool.cmd) that does nothing and returns failure.

如果你真的急于压制所有自动冲突解决的尝试,我相信你可以插入一个虚拟的合并工具(通过merge.tool和mergetool.cmd),什么都不做并返回失败。

Having said all of this, I should also say that in my experience with git merges, I have seen plenty of conflicts but cannot remember a single incorrect automatic merge. I personally trust it's merging capabilities. Checking up on it after should really be plenty.

说完所有这些后,我还应该说,根据我对git merge的经验,我看到了很多冲突,但是记不起一次不正确的自动合并。我个人相信它的合并能力。之后检查它应该是充足的。

#3


I know this is a really old topic, but we found that git diff --name-only was returning too many false positive modified files if the two branches are too differents. Here's what we use at work to perform review code for commits of a new branch against our feature branch (possibly already partially merged in the feature branch).

我知道这是一个非常古老的话题,但是我们发现git diff --name-only返回了太多的误报修改文件,如果这两个分支太不同了。这是我们在工作中使用的功能,用于针对我们的功能分支执行新分支的提交的审阅代码(可能已经在功能分支中部分合并)。

being in our new_branch and under *nix system we use this command:

在我们的new_branch和* nix系统下,我们使用这个命令:

git show --name-only $( git cherry -v feature_branch | grep '^+' | awk '{ print($2) }' ) | egrep -v '^(commit |Author:|Date:|\s|$)' | sort -u

replacing feature_branch by the name of the branch you want to check modified files against.

将feature_branch替换为要检查修改文件的分支的名称。

The advantages of this techniques is that it really sorts only files modified by commits that belong to your branch and that are not already merged in your feature_branch.

这种技术的优点是它实际上只对由属于您的分支的提交修改的文件进行排序,并且这些文件尚未在您的feature_branch中合并。

If you want to check between two commits SHA1 and SHA2 you also can do:

如果要在两个提交SHA1和SHA2之间进行检查,您还可以执行以下操作:

git show --name-only $( git cherry -v SHA1 SHA2 | grep '^+' | awk '{ print($2) }' ) | egrep -v '^(commit |Author:|Date:|\s|$)' | sort -u

#4


this will list the top 20 files of your branch which has changed most frequently

这将列出最常更改的分支的前20个文件

git log --pretty=format: --name-only | sort | uniq -c | sort -rg | head -20

git log --pretty = format: - name-only |排序| uniq -c | sort -rg |头-20