为什么Git中没有撤消/重做? [英] Why is there no undo/redo in Git?
问题描述
$ git commit ...
$ git reset --soft HEAD ^
$编辑
$ git add ....
$ git commit -c ORIG_HEAD
或者要撤消拉,您可以按照这里,
$ git reset --hard
但这些命令不一定可以互换。 Git不允许简单的撤消和重做命令吗?与它背后的哲学有什么关系?另外,我对其他版本控制系统没有多少经验,但是他们中的任何一个都提供了一个简单的撤消和重做命令? 解决方案
这样一个概念有几个问题: 并非所有的操作都是可逆的。有时候,这是因为Git没有记录足够的信息来推断先前的状态 - 总的来说,这样做的代价非常昂贵。有时它是诸如
git reset --hard
或 git clean
之类的东西,它会破坏未跟踪的更改。为了撤消它们,它必须不断自动备份。有时候这是因为撤销的概念是不明确的 - 正如你自己指出的那样,撤销提交有很多方法。
即使所有东西都有明确的定义,它也是荒谬的工作实施。你如何确定什么是单一行为?一个Git命令可能会做很多事情。它应该撤消一步,整个事情?如果你已经运行了一个zillion命令,每个步骤都很小,并且你想要全部撤消这些命令呢?它必须是完美的,完全完美的,因为这种功能将被没有经验的用户使用,他们不知道如何从任何错误中恢复过来。
因此,就像Git为您提供工具来做事情一样,它为您提供了工具来查看您所做的事情,并在需要时自行解决。
另外,关于重做,正如您在问题中所定义的那样,它会重复一个命令,而不是再次执行原始操作。当你重新提交一个提交时,它是一个不同的提交。重新运行以前的命令是命令行shell设计的目的。 Git不需要重新创建它。
As far as I know, when you want to undo something in Git you have to explicitly find the command to undo whatever it is you've done and issue it. For instance, one way among many to undo a commit and redo it is to follow the example from here,
$ git commit ...
$ git reset --soft HEAD^
$ edit
$ git add ....
$ git commit -c ORIG_HEAD
Or to undo a pull, you can follow the instructions from here,
$ git reset --hard
But these commands do not necessarily work interchangeably. Is there a reason why Git does not allow simple undo and redo commands? Something to do with the philosophy behind it? Also, I don't have much experience with other version control systems, but do any of them offer a simple undo and redo command?
There are several problems with such a notion:
Not all operations are reversible. Sometimes this is because Git doesn't record enough information to deduce the prior state - that'd be prohibitively expensive in general. Sometimes it's things like
git reset --hard
orgit clean
, which destroy untracked changes. In order to undo them, it'd have to be continuously automatically backing up. Sometimes this is because the notion of undo is ambiguous - as you yourself pointed out, there are many ways to undo a commit.If an operation is reversible, and it involved some sort of history, should the undo/redo also be in the history, or should they make it vanish? Should a commit be undone by resetting back, or by reverting (creating another commit to cancel it)?
Without logging every last thing you do, how would you know what the most recent operation was? Say you added a file to the index, and created a branch. There's no record of which was first.
Even if everything were clearly defined, it'd be an absurd amount of work to implement. How do you decide what constitutes a single action? A single Git command might do many things. Should it undo one step, the whole thing? What if you've run a zillion commands each doing a tiny step and you want to undo it all? And it'd have to be perfect, completely perfect, because it's the kind of feature that will be used by inexperienced users who'll have no idea how to recover from any mistake.
So, just as Git gives you the tools to do things, it gives you the tools to see what you've done, and undo things yourself if so desired.
Also, with respect to "redo", as you defined it in your question, it's repeating a command, not doing the original operation again. When you redid a commit, it was a different one. Re-running a previous command is something that command-line shells were designed to do. Git doesn't need to reinvent it.
这篇关于为什么Git中没有撤消/重做?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!