我一直在用git工作一个多月.事实上我昨天才第一次使用复位,但软复位对我来说仍然没有多大意义.
据我所知,我可以使用软重置编辑提交而不改变索引或工作目录git commit --amend.
这两个命令是否真的相同(reset --softvs commit --amend)?有任何理由在实际中使用其中一个吗?更重要的是,reset --soft除了修改提交之外还有其他用途吗?
Von*_*onC 98
git reset所有关于移动HEAD,通常是分支参考.
问题:工作树和索引怎么样?
当使用--soft,移动HEAD,最常更新分支ref,而且只有HEAD.
这与以下不同commit --amend:
commit --amend只是不移动HEAD,同时允许重做当前提交)刚刚找到这个组合的例子:
all into one(章鱼,因为合并了两个以上的分支)提交合并.
Tomas"wereHamster"Carnecky在他的"Subtree Octopus merge"文章中解释道:
- 如果要将一个项目合并到另一个项目的子目录中,并且随后使子项目保持最新,则可以使用子树合并策略.它是git子模块的替代品.
- 章鱼合并策略可用于合并三个或更多分支.正常策略只能合并两个分支,如果你尝试合并更多,git会自动回退到章鱼策略.
问题是你只能选择一种策略.但是我希望将两者结合起来以获得一个干净的历史记录,其中整个存储库被原子地更新为新版本.
我有一个超级项目,让我们称它
projectA,和一个子项目,projectB我合并到一个子目录projectA.
(这是子树合并部分)
我也在维护一些本地提交.
ProjectA定期更新,projectB每隔几天或几周都有一个新版本,通常取决于特定版本projectA.当我决定更新这两个项目时,我不会简单地从中拉出来
projectA,projectB因为这将为整个项目的原子更新创建两个提交.
相反,我创建一个单一的合并提交它结合了projectA,projectB和我的本地提交.
这里棘手的部分是这是一个章鱼合并(三个头),但projectB需要与子树策略合并.所以这就是我做的:
# Merge projectA with the default strategy:
git merge projectA/master
# Merge projectB with the subtree strategy:
git merge -s subtree projectB/master
Run Code Online (Sandbox Code Playgroud)
在这里,作者使用a reset --hard,然后read-tree恢复前两个合并对工作树和索引所做的事情,但这reset --soft可以帮助:
如何重做那两个合并,哪些有效,即我的工作树和索引是很好,但无需记录这两个提交?
# Move the HEAD, and just the HEAD, two commits back!
git reset --soft HEAD@{2}
Run Code Online (Sandbox Code Playgroud)
现在,我们可以恢复Tomas的解决方案:
# Pretend that we just did an octopus merge with three heads:
echo $(git rev-parse projectA/master) > .git/MERGE_HEAD
echo $(git rev-parse projectB/master) >> .git/MERGE_HEAD
# And finally do the commit:
git commit
Run Code Online (Sandbox Code Playgroud)
所以,每次:
git reset --soft 是答案.
Sha*_*tin 37
"糟糕.这三个提交可能只是一个."
因此,撤消最后3次(或其他)提交(不影响索引和工作目录).然后将所有更改作为一个提交.
> git add -A; git commit -m "Start here."
> git add -A; git commit -m "One"
> git add -A; git commit -m "Two"
> git add -A' git commit -m "Three"
> git log --oneline --graph -4 --decorate
> * da883dc (HEAD, master) Three
> * 92d3eb7 Two
> * c6e82d3 One
> * e1e8042 Start here.
> git reset --soft HEAD~3
> git log --oneline --graph -1 --decorate
> * e1e8042 Start here.
Run Code Online (Sandbox Code Playgroud)
现在,所有更改都会保留,并且可以作为一个更改提交.
这两个命令是否真的相同(reset --softvs commit --amend)?
有任何理由在实际中使用其中一个吗?
commit --amend 从最后一次提交添加/ rm文件或更改其消息. reset --soft <commit> 将几个顺序提交组合成一个新的.更重要的是,reset --soft除了修改提交之外还有其他用途吗?
Sim*_*mon 16
我用它来修改不仅仅是最后一次提交.
假设我在提交A中犯了一个错误然后提交了B.现在我只能修改B.所以我这样做git reset --soft HEAD^^,我纠正并重新提交A然后重新提交B.
当然,对于大型提交来说它不是很方便......但是你不应该做大量的提交;-)
del*_*rux 13
另一个潜在用途是作为存储的替代方法(有些人不喜欢,例如https://codingkilledthecat.wordpress.com/2012/04/27/git-stash-pop-considered-harmful/).
例如,如果我正在分支机构并且需要在master上紧急修复某些东西,我可以这样做:
git commit -am "In progress."
Run Code Online (Sandbox Code Playgroud)
然后结帐大师并做修复.当我完成后,我会回到我的分支机构做
git reset --soft HEAD~1
Run Code Online (Sandbox Code Playgroud)
继续在我离开的地方工作.
您可以使用git reset --soft更改您希望拥有的版本作为索引和工作树中所做更改的父级.有用的情况很少见.有时您可能会认为工作树中的更改应属于不同的分支.或者你可以使用它作为一种简单的方法将几个提交折叠成一个(类似于壁球/折叠).
请参阅VonC的这个答案以获得一个实际的例子: 在Git中压缩前两个提交?
一种可能的用法是当您想要在另一台机器上继续工作时.它会像这样工作:
签出一个类似藏匿名称的新分支,
git checkout -b <branchname>_stash
Run Code Online (Sandbox Code Playgroud)推开你的藏匿分支,
git push -u origin <branchname>_stash
Run Code Online (Sandbox Code Playgroud)切换到您的其他机器.
拉下你的藏匿处和现有的树枝,
git checkout <branchname>_stash; git checkout <branchname>
Run Code Online (Sandbox Code Playgroud)您现在应该在现有分支上.合并来自隐藏分支的更改,
git merge <branchname>_stash
Run Code Online (Sandbox Code Playgroud)在合并之前将现有分支软重置为1,
git reset --soft HEAD^
Run Code Online (Sandbox Code Playgroud)删除你的藏匿分支,
git branch -d <branchname>_stash
Run Code Online (Sandbox Code Playgroud)同时从原点删除您的隐藏分支,
git push origin :<branchname>_stash
Run Code Online (Sandbox Code Playgroud)继续处理您的更改,就好像您正常隐藏它们一样.
我想,在未来,GitHub和co.应该以更少的步骤提供这种"远程存储"功能.
一个实际用途是如果你已经提交到你的本地仓库(即.git commit -m)然后你可以通过执行git reset来反转最后一次提交--soft HEAD~1
另外据您所知,如果您已经进行了更改(例如使用git add.),那么您可以通过执行git reset来反转分段 - 混合HEAD或者我通常也只是使用git reset
最后,git reset --hard擦除所有内容,包括你的本地更改.〜后头告诉你从顶部有多少提交.
| 归档时间: |
|
| 查看次数: |
173877 次 |
| 最近记录: |