这个工作流程是否有什么问题可以获得类似的壁球结果?
draft_feature_a
feature_a
git checkout draft_feature_a $(git diff --name-only master draft_feature_a)
现在您只有最后的更改,您可以使用相当提交的消息提交它们。
答案 0 :(得分:2)
它不会捕获文件删除,例如:
$ git checkout draft_feature_a $(git diff --name-only master draft_feature_a)
error: pathspec 'ttt.py' did not match any file(s) known to git.
你可以用实际的rebase-and-squash-etc做同样的事情(我在下面使用“fixup”,几乎是一样的,真的;原始提交仍然可以在draft_feature_a
上查看):
$ git checkout -b draft_feature_a
[work, commit, etc - I made two commits: add newfile and rm ttt.py]
$ git checkout master
Switched to branch 'master'
$ git checkout -b feature_a
Switched to a new branch 'feature_a'
$ git merge draft_feature_a
Updating 523bacb..3a486fc
Fast-forward
newfile | 0
ttt.py | 14 --------------
2 files changed, 14 deletions(-)
create mode 100644 newfile
delete mode 100644 ttt.py
git rebase -i master
[edit to make everything but the first a "fixup"]
...
2 files changed, 14 deletions(-)
create mode 100644 newfile
delete mode 100644 ttt.py
Successfully rebased and updated refs/heads/feature_a.
$ git commit --amend
[edit commit message]
我实际上使用这样的工作流程,虽然大多数时候我只是“git rebase -i”草稿工作。请注意,无论您是否创建单独的“草稿”分支,原始提交都可用,它们只是丢失了名称,您必须通过reflog来查找提交ID。您可以添加新名称而不是创建新分支和“git merge”-ing:
(首先,让我们清理上一个例子)
$ git checkout master
Switched to branch 'master'
$ git branch -D draft_feature_a
Deleted branch draft_feature_a (was 3a486fc).
$ git branch -D feature_a
Deleted branch feature_a (was 0fc36f0).
(现在是一个新例子)
$ git checkout -b feature_a
Switched to a new branch 'feature_a'
[work work work]
[time to clean up, let's stick a label on this version so I can find it easily:]
$ git branch messy_feature_a feature_a
$ git rebase -i master
一旦rebase完成,所有东西被压扁,修复,重新排列,提交消息编辑等等,如果我决定搞砸了什么,我所有的“草稿”(低质量/凌乱)工作在“凌乱”的名称下仍然可以使用名称。当我满意并且不想要旧名称时,我会手动删除它(git branch -D
)。
理解这一点的诀窍是每次你在git中做东西时,你只会添加新的提交。旧的在你的回购中留下来,直到(最终)你做一些隐含的或明确的“垃圾收集”它们。只要它们具有分支标签名称(或其他“可见”名称,如标记),使得提交可以通过3a486fc
样式SHA1名称之外的其他名称进行命名,它们将持续“永久”。删除分支只会删除标签。一个月或三个月后,未标记的提交最终被垃圾收集。 (更准确地说,它在reflog中仍有一个名称,直到过期:reflog条目有时间限制。请参阅git reflog
的文档,尤其是--expire=<time>
参数。)
类似地,“rebase”进行一系列新的提交,将所有旧提交留在那里。当rebase完成时,git将标签从旧系列提交的末尾剥离并粘贴到新系列提交的末尾:
A -- B -- C [label: master]
\
D -- E [label: feature_a]
[rebase feature_a on master, and squash or fixup to make commit DE which is D+E]
A -- B -- C [label: master]
| \
| D -- E [no label!]
\
DE [label: feature_a]
如果在执行rebase之前添加额外标签,则会剥离当前分支feature_a
标签并移动到新提交,但另一个标签(messy_feature_a
)会粘在一起并且让您轻松访问提交E,从而使整个链(D和E分支C)。
答案 1 :(得分:1)
您似乎使用的是Linux风格的系统$(git...
。这应该工作,并将处理已删除的文件:
git checkout -b feature_a master
git diff draft_feature_a | patch -p1 -R
答案 2 :(得分:0)
这是我的新工作流程:
draft_feature_a
master
合并到draft_feature_a
,并解决所有冲突。draft_feature_a
结帐新分行final_feature_a
(git checkout -b final_feature_a
)git reset --soft master
我知道我可以使用git rebase -i master
和压缩来完成所有这些操作,但是当发生冲突时,我会感到很复杂。