在git中提交替代分支(保留工作副本未修改)

时间:2017-11-02 11:12:38

标签: git branching-and-merging git-commit

我正在分支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),还是其他什么?我能想到的所有组合都会在某些时候弄乱我的工作副本。

3 个答案:

答案 0 :(得分:0)

使用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

答案 1 :(得分:0)

鉴于您对“为什么”的描述,我可以告诉您更简单的方法。如果您确定您真的想要使用临时分支,那么当然可以。

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

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

但就像我说的那样,这真的是重新发明轮子。您不需要分支来存储您可以返回的状态。你只需要提交

git commit

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

git rebase -i

您会看到一个提交列表,每个提交都标记为pick;这是git rebase的TODO列表。找到您不想要的提交,并将 next commit命令更改为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

将从您的分支历史记录中删除“临时”提交。是的,这是一个历史重写,但你在共享分支之前做了(这就是整点)所以没关系。

答案 2 :(得分:0)

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

git commit -a
git branch attempt1
git reset HEAD^

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

索引结束为空。如果要在索引中进行更改,请使用软重置(git reset --soft HEAD^)。