我有以下两个文件不同的分支
大师
|_ document.txt
|_ document_two.txt
|_ document_three.txt
发展
|_ document.txt
|_ document_two.txt
|_ document_three.txt
|_ virus.exe // want to get rid of that
这是两者的git log
结果(从上到下)
大师
commit: fdsdfsf1342re5252423425242234 (master, development)
add document one
commit: 563523523g233g5232sdfawe22434 (master, development)
add document two
commit: 56652u747241523g52352fsdfawew (master, development)
add document three
发展
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
我要清理 development 分支,以使其具有主控的所有源文件状态,并且除去virus.exe
文件。
我已经找到了使 master 状态覆盖 development 文件状态的方法。
在此处阅读:Make the current Git branch a master branch
但是我也想摆脱 master 的工作集中不存在的文件。在此示例中,这将是文件virus.exe
。仅创建主组件的新 development 分支是不可行的,因为将 development 分支保留为 orphan 很重要。当通过/关闭 master 分支覆盖/分支 development 分支时,它将丢失 orphan 状态,因为它将适应的整个历史记录>大师
有人知道一种方法:
编辑: 我找到了使文件有所不同的命令:
$ git diff-tree -r --name-status --diff-filter=A master..development
A virus.exe
是否有一种优雅的方法可以直接使用输出从开发分支中删除?我会在以下地方使用它:
git checkout development && git rm virus.exe && git commit -m "clean development" && git push origin
答案 0 :(得分:1)
分支没有工作集。 (嗯,也许他们会这么做,因为您尚未定义工作集,但是Git也没有定义工作集。但是由于我不知道您的意思,所以我正在使用 working设置作为工作树的别名,是定义明确的分支,分支没有工作树。)
分支名称的作用是选择一个特定的提交。然后,该提交有一些父提交(如果是合并,则有多个提交);父级有自己的父级,依此类推,形成了一个提交链。结果,我们可以说分支(或分支名称)包含了一组提交::这些是可以从名称中到达的提交。有关所有这些的良好介绍,请参见Think Like (a) Git。
每个提交都有一个存储的 tree 或快照。如您所见,git diff-tree
是所谓的 plumbing命令(可编写脚本的工作马),用于比较两次提交中的两棵树:
git diff-tree -r commit1 commit2
以递归方式(-r
)比较整个树,比较两个快照中包含的所有文件。您可以拼写commit1..commit2
:这表示完全相同的内容,在比较中将commit1
用作左侧,将commit2
用作右侧。此比较的输出实质上是一系列指令,例如,向该文件添加一些行,从该文件中删除一些行,然后您将使附加到commit1
的树与所附加的树匹配到commit2
。
您可以添加诸如--name-only
或--name-status
和--find-renames
之类的选项,并带有可选的相似性索引值(百分比),以使Git计算重命名的位置,然后进行更改,则文件生成的指令序列比简单的删除文件A短,并使用这些内容从头开始创建新文件B 。例如,较短的序列可能是将A重命名为B,然后删除第17行,显然比删除文件A短得多,然后用以下10,000行创建文件B:[非常长行列表] 。
面向用户的前端git diff
命令实际上运行git diff-tree
或git diff-index
或其他任何命令,但使用用户的配置(diff.renames
和{{1}例如}),并通过 pager 发送输出,进行着色等等。 Git称这些命令为 porcelain (瓷器),因为它们应该是用户友好的(相对于管道,隐藏在墙后,看不见)。
提交 new 提交时,Git会存储一个新的快照。当您运行diff.renameLimit
时,Git会根据其 index 中Git的内容构建新快照。新提交的 parent 是当前分支的旧提示。新的提交成为当前分支的尖端。这就是分支的增长方式。
您使用的各种命令(例如git commit
或git rm
)在 index 上运行。您使用git add
将分支的尖端提交提取到该索引中。索引中 中存储的文件很难看-使用git checkout branch
可以获得完整的列表,但这很少有用。无论如何,这些文件在索引中并最终(最终)被冻结为提交,因此它们都是特殊的仅Git形式。因此,要使用这些文件,当您使用Git提取提示提交时,还需要使用Git将所有文件都提取到工作树中。
工作树具有那些普通格式的文件,您和您的计算机可以在其中以普通方式使用它们。但是您在此工作树中所做的所有操作实际上都是针对索引的,因为索引包含了 next 提交中的内容。运行git ls-files --stage
会将索引内容打包(冻结)为快照,并将其添加为分支的新技巧。
因此,如果您比较两个提交(使用git commit
或git diff
),然后对索引进行一些更改并进行新的提交,您正在做的就是更改索引并将其用于进行新的提交。两次提交的比较取决于您。请注意,您还可以使用git diff-tree
(瓷器)或git diff --cached
(管道)比较索引对 的任何提交。而且,您还可以使用这些命令比较索引与工作树,或提交与工作树。