提交到git中的备用分支(不修改工作副本)



我正在处理一个分支topic。我已经做了一些更改,我想在分支attempt1上提交这些更改。提交这些更改后,我希望从当前状态继续处理topic(而不是回到topic上的最后一次提交)。

这样做的原因是,在更改足够好以进入已发布的分支之前,我需要做更多的工作(我定期推送topic),但我想保存当前状态的副本,以防我把返工搞砸。我不想在做这件事的时候更改我的工作副本。我希望最后得到一个空索引。

请注意,我想让attempt1保留一段时间——这不仅仅是一个非常临时的提交,我将在几分钟后重新提交。有时我决定改变我在topic上的方法,同时在attempt1上寻求另一种方法。我想创建一个分支,而不仅仅是隐藏一个提交。

此外,我正在追求一些稳健的东西,所以交互式重新定基已经过时了。暂时提交到topic,然后将提交移动到一个新的分支就可以了,只要我可以在不修改工作副本的情况下做到这一点。

在图形方面,我处于状态

HEAD
|
v
A  topic

有未提交的更改,我想转到

HEAD
|
v
A  topic

B  attempt1

有一个与B.相同的未更改的工作副本

然后我可以做git checkout -b attempt1(然后是git add新文件和git rm删除文件)git commit -a。但是,如果不修改工作树,我该如何切换回topic

基本上,我该如何进行

git commit --to-alternate-branch=attempt1

或(在创建并提交给attempt1之后)

git checkout --do-not-modify-working-tree topic

或者git stash --no-revert(后面跟着git branch attempt1 stash@{0}),或者其他什么?我能想到的所有组合都会在某个时候把我的工作副本搞砸。

确保使用git add添加了任何新文件,并且使用git rm声明了任何删除的文件。然后:

git commit -a
git branch attempt1
git reset HEAD^

这会在当前分支上创建一个提交,然后撤消该提交(混合重置会更改当前分支指向的位置,但不会修改工作副本)。在这两者之间,创建一个新的分支,其提示就是提交,而不切换到该分支。

索引最终为空。如果要更改索引,请使用软重置(git reset --soft HEAD^)。

根据您对"为什么"的描述,我可以告诉您有一种更简单的方法。如果你决定只想使用一个临时分支,那么你当然可以。

现在,AnoE建议的方法通常会起作用,但可能无法正确反映删除。有多种方法可以为此调整程序,但我讨厌试图跟踪它们;所以你可以用藏匿处。

git stash
git checkout -b attempt1
git stash apply
git commit
git checkout topic
git stash pop

但正如我所说,这一切都是在重新发明轮子。你不需要一个分支来存储你可以返回的状态。你只需要一个提交

git commit

你会争辩说,你永远不想推动承诺;这没问题。如果你完成了你的工作并且它很好,

git rebase -i

您将看到一个提交列表,每个提交都标记为pick;这是CCD_ 22的TODO列表。找到您不想要的提交,并将下一个提交的命令更改为squash。例如,TODO列表显示为

pick 00000001 first attempt
pick 00000002 here's a commit I want to push

你把它改成

pick 00000001 first attempt - don't push this
squash 00000002 but here's a commit I want to push

并且"临时"提交将从您的分支历史记录中删除。是的,这是一次历史重写,但您在共享分支之前进行(这就是重点),所以这很好。

使用git

按照你在问题中描述的方式创建你的新分支attempt1(也就是说,像往常一样)。然后:

git checkout topic
git checkout attempt1 .

git help checkout展示了该变体的确切功能。这将使你的新索引像attempt1,但如果你愿意,你可以很容易地取消分级。

请注意,如果您的原始状态同时包含已暂存和未暂存的更改,则此区别将丢失。

不使用git

假设您的工作目录名为src。。。

cd ..
cp -r src src2  
cd src2
git branch attempt1
git add ... 
git commit
git push origin attempt1
cd ..
rm -rf src2

有点像大锤,但它能满足你的要求。

如果您没有origin或不想在那里推送,那么不要推送:

cd ../src
git remote add tmp PATHTOSRC2
git fetch tmp
git branch attempt1 tmp/attempt1
git remote del tmp
rm -rf ../src2

最新更新