简体   繁体   English

如何获取两个 git 分支的工作集(非提交)之间的差异

[英]How to get the difference between the working sets (not commits) of two git branches

I have the following two branches that differ in files我有以下两个文件不同的分支

master掌握

 |_ document.txt
 |_ document_two.txt
 |_ document_three.txt

development发展

 |_ document.txt
 |_ document_two.txt
 |_ document_three.txt
 |_ virus.exe // want to get rid of that

And these are the git log results of both ( from top to bottom )这些是两者的git log结果(从上到下

master掌握

commit: fdsdfsf1342re5252423425242234 (master, development)
add document one

commit: 563523523g233g5232sdfawe22434 (master, development)
add document two

commit: 56652u747241523g52352fsdfawew (master, development)
add document three

development发展

commit: fdsdfsf1342re5252423425242234 (master, development)
add document one

commit: 563523523g233g5232sdfawe22434 (master, development)
add document two

commit: 1213421g233g5232s41dfawe22434 (development)
ADD VIRUS.EXE ! XXX

commit: 5423345652u7433g52352fsdf1223 (development)
change document three completly

commit: 56652u747241523g52352fsdfawew (master, development)
add document three

Goal目标

I want to clean up the development branch so it has all the sourcefile states of master and has the virus.exe file removed.我想清理开发分支,以便它具有 master 的所有源文件状态删除了virus.exe文件。

I already found ways to have the master state overwrite the development file states.我已经找到了让状态覆盖开发文件状态的方法。

Read here : Make the current Git branch a master branch在这里阅读使当前的 Git 分支成为主分支

But I also want to get rid of files that do not exist within the working set of master .但我也想摆脱master工作集中不存在的文件。 In this example this would be the file virus.exe .在本例中,这将是文件virus.exe Just creating a new development branch of the master is not an option because it is important to leave the development branch as an orphan .仅创建 master 的新开发分支不是一种选择,因为将development分支保留为孤立分支很重要。 When overwriting/branching the development branch by/off the master branch it will lose the orphan state since it will adapt the whole history of master当覆盖/分支通过/开发分支关闭分支将失去孤立状态,因为它会适应主人的整个历史

Does anybody know a way to:有没有人知道一种方法:

  • get the differences between two branches in files?获取文件中两个分支之间的差异? not their commit diffs不是他们的提交差异
  • removing all found differences in files by a final commit (to keep history intact) ?通过最终提交删除所有发现的文件差异(以保持历史完整)?

Edit : I found the command to give me the difference in files:编辑:我找到了给我文件差异的命令:

$ git diff-tree -r --name-status --diff-filter=A master..development
A       virus.exe

Is there an elegant way to directly use the output to remove from the development-branch?有没有一种优雅的方法可以直接使用输出从开发分支中删除? I would kinda use it in:我会在以下方面使用它:

git checkout development && git rm virus.exe && git commit -m "clean development" && git push origin

Branches don't have working sets.分支没有工作集。 (Well, maybe they do, since you have not defined working set , but Git does not define working set either. But since I don't know what you mean, I'm using working set as an alias for work-tree , which is well-defined, and branches don't have work-trees.) (好吧,也许他们会这样做,因为您尚未定义工作集,但 Git 也没有定义工作集。但由于我不知道您的意思,所以我使用工作集作为工作树的别名,即明确定义的,并且分支没有工作树。)

What branch names do is select one particular commit.分支名称的作用是选择一个特定的提交。 That commit then has some parent commit (or more than one if it is a merge);然后该提交有一些父提交(如果是合并,则有多个); the parent has its own parent, and so on, forming a chain of commits.父级有自己的父级,依此类推,形成一个提交链。 As a result we can say that a branch (or branch name) contains some set of commits: these are the commits that are reachable from the name.因此,我们可以说一个分支(或分支名称)包含一些提交:这些是可以从名称访问的提交。 For a good introduction to all of this, see Think Like (a) Git .有关所有这些的详细介绍,请参阅Think Like (a) Git

Each commit has a stored tree or snapshot.每个提交都有一个存储或快照。 As you have found, git diff-tree is the so-called plumbing command (script-able work-horse) for comparing two trees as found in two commits:正如您所发现的, git diff-tree是所谓的管道命令(可编写脚本的工作马),用于比较两次提交中发现的两棵树:

git diff-tree -r commit1 commit2

compares the entire trees, recursively ( -r ), comparing all the files contained in the two snapshots.递归地比较整个树( -r ),比较两个快照中包含的所有文件。 You can spell this commit1..commit2 : it means exactly the same thing, use commit1 as the left side and commit2 as the right side in the comparison.您可以拼出这个commit1..commit2 :它意味着同样的事情,使用commit1的左侧和commit2为右侧的比较。 The output of this comparison is essentially a sequence of instructions, eg, add some lines to this file, remove some lines from that one, and you'll cause the tree attached to commit1 to match the tree attached to commit2 .这种比较的输出本质上是一个指令序列,例如,向该文件添加一些行,从该文件中删除一些行,您将导致附加到commit1的树与附加到commit2的树相匹配。

You can add options like --name-only or --name-status , and --find-renames with an optional similarity index value—a percentage—to have Git compute places where renaming, then changing, a file produces a shorter instruction sequence than the simpler remove file A, and create new file B from scratch with these contents .您可以添加--name-only--name-status--find-renames等选项,并带有可选的相似性索引值(百分比),让 Git 计算重命名和更改文件的位置,从而生成更短的指令序列比更简单的删除文件 A,并使用这些内容从头开始创建新文件 B。 For instance, perhaps the shorter sequence is rename A to B, then remove line 17, which is clearly much shorter than remove file A, then create file B with these 10,000 lines: [very long list of lines] .例如,也许较短的序列是将 A 重命名为 B,然后删除第 17 行,这显然比删除文件 A短得多,然后用这 10,000 行创建文件 B:[非常长的行列表]

The front-end, user-oriented git diff command in effect runs git diff-tree or git diff-index or whatever, but with the user's configuration ( diff.renames and diff.renameLimit for instance) in mind, and with output sent through a pager , colorized, and so on.前端的、面向用户的git diff命令实际上运行git diff-treegit diff-index或其他什么,但考虑到用户的配置(例如diff.renamesdiff.renameLimit ),并且输出通过寻呼机、彩色等。 Git calls these commands porcelain as they are supposed to be user-friendly (vs the plumbing, hidden behind the walls, out of sight). Git 将这些命令称为瓷器,因为它们应该是用户友好的(相对于管道,隐藏在墙后,看不见)。

When you make a new commit, you have Git store a new snapshot.当你进行新的提交时,你让 Git 存储一个新的快照。 Git builds the new snapshot from whatever Git has in its index at the time you run git commit .在您运行git commit时,Git 从其索引中的任何 Git 构建新快照。 The new commit's parent is the old tip of the current branch;新提交的父级是当前分支的旧提示; the new commit becomes the tip of the current branch.新提交成为当前分支的尖端。 This is how branches grow.这就是树枝生长的方式。

The various commands you use, such as git rm or git add , operate on the index .您使用的各种命令,例如git rmgit add ,都会对index进行操作。 You use git checkout branch to extract the tip commit of a branch into this index.您使用git checkout branchgit checkout branch的提示提交提取到此索引中。 The files stored in the index are hard to see—you can get a complete listing with git ls-files --stage , but that's rarely very useful.存储索引中的文件很难看到——您可以使用git ls-files --stage获得完整的列表,但这很少很有用。 These files, in the index and (eventually) frozen into a commit, are in a special Git-only form anyway.这些文件在索引中并(最终)冻结到提交中,无论如何都是特殊的 Git-only 形式。 So to work with those files, when you have Git extract the tip commit, you also have Git extract all the files into a work-tree .所以为了处理这些文件,当你让 Git 提取提示提交时,你还需要 Git 将所有文件提取到一个工作树中

The work-tree has those files in their ordinary format, where you, and your computer, can work with them in ordinary ways.工作树以普通格式保存这些文件,您和您的计算机可以在其中以普通方式使用它们。 But everything you do in this work-tree is really aimed at fussing with the index, because it's the index that contains what goes in the next commit.但是你在这个工作树中所做的一切实际上都是为了处理索引,因为它是包含下一次提交内容的索引。 Running git commit packages up (freezes) the index contents into a snapshot, and adds that as the new tip of the branch.运行git commit将索引内容打包(冻结)为快照,并将其添加为分支的新提示。

Hence, if you compare two commits (with git diff or git diff-tree ), then make some changes to your index and make a new commit, what you are doing is changing your index and using it to make a new commit.因此,如果您比较两个提交(使用git diffgit diff-tree ),然后对索引进行一些更改并进行新的提交,那么您所做的就是更改索引并使用它来进行新的提交。 The comparison of the two commits is up to you.两次提交的比较取决于您。 Note that you can also compare any one commit to your index, using git diff --cached (porcelain) or git diff-index --cached (plumbing).请注意,您还可以使用git diff --cached (瓷器)或git diff-index --cached (管道)将任何一个提交您的索引进行git diff --cached And, you can compare index vs work-tree, or a commit vs work-tree, also using these commands.而且,您还可以使用这些命令比较索引与工作树,或提交与工作树。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM