比我承认的更常见,我会投入一些我不打算做的线/帅哥。我想要撤消。
但是让我们理解我不打算提交的撤消更改意味着什么。这并不意味着删除更改。从字面上撤消提交的行更改意味着存在删除它们的提交,但更改将保留为“未暂存”。
请不要建议重置头,因为这不能完成撤消“某些行/帅哥”(但不是其他行)的具体任务。理解我希望在这里做的事情比这更复杂,因为它涉及一个恢复一组特定更改的提交(但不是该提交中的所有更改),然后重做这些更改,但是作为未分阶段。 / p>
我怀疑我是唯一一个曾经想要这样做的人。
在git中有一个相当简单的方法吗?在SourceTree中怎么样?
答案 0 :(得分:2)
您可能应重置,可能使用--soft
,然后使用git checkout -p
,然后使用git commit
。这通常是最简单和最简单的。但你不能 这样做。
接下来是一个很长的解释(带有一些图形图片)。
git reset
一旦你进行了一些提交,它们就会永久存储在那个提交中。让我们备份很多,因为Git并没有像许多人认为的那样存储文件。
例如,考虑这个微小的存储库只需要三次提交。他们的实际ID是一些难以理解的哈希字符串;为简单起见,我将A
标记为C
而不是:
A <-B <-C <-- master
名称master
包含提交C
的哈希ID。提交C
包含其父提交{1}的哈希ID,提交B
包含其父提交B
的哈希ID。由于A
是第一次提交( root 提交),因此它没有父级,并且Git将在显示提交A
后停止遍历历史记录。
我们还说A
指向 master
,C
指向C
,依此类推。
这三个提交中的每个提交都是您的来源的一系列快照。
进行新提交只是意味着提交指向B
的提交D
,然后将名称C
更改为指向{{1 }}:
master
这个新提交是永久性的,不可更改的。
现在,每个提交 是整个源的完整独立快照。提交D
的每个文件都与您运行A <-B <-C <-D <-- master
时的(暂存)表单完全相同。提交D
还包含完全(暂存)形式的每个文件,当您或任何人运行创建git commit
的{{1}}时。要将C
视为更改(来自git commit
),Git必须提取所有C
,然后提取所有D
,然后比较两者看看有什么不同。
同样适用于您的临时区域和工作树中的内容,除了这些是可塑的(非永久性的)这一事实。也就是说,索引/暂存区域包含建议的提交,工作树包含您可以实际处理的文件(因此名称&#34;工作树&#34;)。 / p>
当Git告诉您已经进行了阶段性更改时,Git正在做的是比较索引/暂存区域中的内容与当前提交中的内容,例如commit C
。无论有什么不同,Git都会呈现出一个阶段化的变化&#34;。
当Git告诉您有 un 阶段的更改时,Git正在做的是将工作树中的内容与索引/分段中的内容进行比较 - 区域。无论有什么不同,Git都表现为&#34;未分阶段的变化&#34;。
现在,让我们说你做了C
- 你原来的问题暗示你已经做了这个 - 但你有更多的东西上演 - 即,当时复制到索引/登台区域比你想要的还要多。 D
中的永久存储文件集包含您不想要的表单。
此时,index / staging-area与运行D
时相比没有变化。那么,提交D
中的内容(确切地)匹配索引/登台区域中的内容,这意味着没有任何内容可以进行提交。
由于工作树是它自己独立的实体,现在工作树中的内容仍然是D
之前的内容,所以未暂存的更改仍未解除。但是&#34;上演的变化&#34;已经成为一个完整的快照。
这意味着您需要摆脱提交git commit
以及D
所在的位置。如果您以某种方式执行此操作和更改< em>没有别的,所以名称D
指向提交D
,我们得到这个图:
git reset
Git现在会将master
中的内容与您的索引/登台区域中的内容进行比较,并向您展示&#34;暂停提交&#34;。实际上,它会在你创建C
之前显示为暂停的,恰好是它所显示的内容,因为&#34;索引中的所有内容&#34; (建议的下一次提交)就是 时你所做的 D [abandoned]
/
A--B--C <-- master
。
由于提交不可更改,如果您保留C
并添加更多提交,则在您的存储库历史记录中,您将拥有此不需要的快照。所以你做必须丢弃它 - 但你不一定要用D
来做这件事。但是,如果你这样做,可能更容易。
(我说的每个地方&#34;必须&#34;,它当然是可选的。如果你愿意,你可以保留无用/坏/负值D
提交。但我怀疑你不打算。)
现在让我们看一下 un 上演的一些变化。
假设您执行此重置,实际上是D
或git reset
。这告诉Git将D
向后移动一步,而不触及索引/暂存区域,并且不触及工作树。现在,您可以git reset --soft HEAD^
使用git reset --soft HEAD~1
。这将允许您对索引中的文件副本进行小的更改。
如果您没有执行master
,您仍然可以运行git checkout -p -- <path>
,但是您想要添加提交的哈希ID { {1}},或者某种方式告诉Git查看提交git reset
。这可能就像git checkout -p
一样简单。
如果您执行这些C
命令之一(包含或不包含初始C
),您可以在索引中获取该文件的副本以获得所需的表单。但是,很难告诉 它是否具有您想要的格式,因为无法查看索引中的文件版本。
要查看索引中的内容,通常会运行git checkout -p HEAD^ <path>
(将git checkout -p
与index / staging-area进行比较)或git reset --soft
(以便将索引与工作进行比较) -树)。这并没有直接显示内容;相反,它会向您显示这些内容与的内容有何不同<{1}} - 您可能知道的内容 - 或者来自工作树的内容,您可以见。
这些再次是&#34;阶段性变化&#34; (索引的内容与git diff --cached
提交的内容相比),或者&#34;未分级的更改&#34; (与内容索引相比的工作树的内容)。但他们与HEAD
提交相关。如果尚未运行git diff
,则必须注意添加&#34;提交HEAD
与HEAD
D {{1} D` vs index&#34;。
所以这就是为什么你真的想要从HEAD
开始。
git reset
的默认值为C
如果您运行commit
,而没有" to any changes shown as "commit
,Git将消灭(重置)您当前的索引/暂存区域,将其替换为以前的内容提交。
Git不会触及工作树,所以如果您已经从工作树中仔细构建了索引,那么现在可以重新完成所有工作。但如果这是很多工作,你可能不想要git reset --soft
重置。
不过,这是一个选项,如果你不小心(或在绝望中)运行git reset
或默认--mixed
,还有一些有用的东西。
一旦你按照你想要的方式设置了索引/暂存区,现在就可以进行你想要的提交。
如果你已经提交了git reset HEAD^
,那么提交图是:
--soft
您可以运行--mixed
而不是常规--mixed
。这样做是为了让你的新提交git reset
,并以正常的方式指向D
- 除了一件事:新的提交A--B--C--D <-- master
将作为其父级,提交git commit --amend
。这会将git commit
推到一边并放弃它:
E
但如果你之前master
做了E
或默认C
- 那么你已经将提交D
推到了那边和被遗弃的,所以你可以用通常的方式添加提交 D [abandoned]
/
A--B--C--E <-- master
。
答案 1 :(得分:1)
我很确定您正在寻找-p
source code让您
以
<tree-ish>
(或索引,如果未指定)与工作树之间的差异交互式选择帅哥
答案 2 :(得分:0)
可行解决方案:反向猛烈?
小心 SourceTree 和 GitKraken 反向大块错误...如果你试图反转大块,他们就会有整个文件被反转的错误。我看到GitKraken在2017年10月9日用版本3.1.1修补了它。但我不知道SourceTree的状态。