提交到 git 中的替代分支(保持工作副本不变)
Commit to alternative branch in git (leaving working copy unmodified)
我在分支机构工作 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
按照您在问题中描述的方式(即像往常一样)创建新分支 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
根据您对 "why" 的描述,我可以告诉您有一个更简单的方法。如果您决定只是真的想使用临时分支,那么您当然可以。
现在,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 提交的命令更改为 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
和 "temporary" 提交将从您的分支历史记录中删除。是的,这是一个历史重写,但是你在 共享分支之前这样做 (这就是重点)所以没关系。
确保已使用 git add
添加了任何新文件,并且已使用 git rm
声明了已删除的所有文件。那么:
git commit -a
git branch attempt1
git reset HEAD^
这会在当前分支上创建一个提交,然后撤消该提交(混合重置会更改当前分支指向的位置,但不会修改工作副本)。在两者之间,创建一个新分支,其提示是该提交,而不切换到该分支。
索引最终为空。如果要在索引中进行更改,请使用软重置 (git reset --soft HEAD^
)。
我在分支机构工作 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
按照您在问题中描述的方式(即像往常一样)创建新分支 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
根据您对 "why" 的描述,我可以告诉您有一个更简单的方法。如果您决定只是真的想使用临时分支,那么您当然可以。
现在,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 提交的命令更改为 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
和 "temporary" 提交将从您的分支历史记录中删除。是的,这是一个历史重写,但是你在 共享分支之前这样做 (这就是重点)所以没关系。
确保已使用 git add
添加了任何新文件,并且已使用 git rm
声明了已删除的所有文件。那么:
git commit -a
git branch attempt1
git reset HEAD^
这会在当前分支上创建一个提交,然后撤消该提交(混合重置会更改当前分支指向的位置,但不会修改工作副本)。在两者之间,创建一个新分支,其提示是该提交,而不切换到该分支。
索引最终为空。如果要在索引中进行更改,请使用软重置 (git reset --soft HEAD^
)。