2016-05-03 28 views
3

我欺骗了作者信息。第一次提交。如果它是分支中唯一的提交,我该如何删除第一个和唯一的提交?

但是,似乎大部分rebase或树的修改操作都依赖于其他一些已经存在的commit。

即使我运行Git的交互式rebase命令,我在我的小提交列表中看到的只有一行,“noop”。 :/(运行我对底垫解决了这个混帐树的rootgit rebase -i --root,但删除行的第一次提交我做实际上并没有从树中删除它。)

衍合上root顶部或第一提交,不起作用。

[[email protected] vagrant]$ git rebase -i HEAD~1 
fatal: Needed a single revision 
invalid upstream HEAD~1 
[[email protected] vagrant]$ git rebase -i HEAD 
Unknown command: rnoop 
Please fix this using 'git rebase --edit-todo'. 
[[email protected] vagrant]$ git rebase --edit-todo 
[[email protected] vagrant]$ git rebase --abort 

下看起来像一个相关的可能的备选答案,但我想更多的东西,或者至少更具体的,是值得为这个特殊情况下的答案:

Delete commits from a branch in Git

这对方的回答(How do you undo the last commit?)得到如下:

[[email protected] vagrant]$ git reset --soft HEAD~ 
fatal: ambiguous argument 'HEAD~': unknown revision or path not in the working tree. 
Use '--' to separate paths from revisions, like this: 
'git <command> [<revision>...] -- [<file>...]' 
[[email protected] vagrant]$ git reset --soft HEAD 

在这里,对于那些仍然在阅读本,是VIM缓冲与noop我前面提到的:

noop 

# Rebase 3d1c632..3d1c632 onto 3d1c632 (1 command(s)) 
# 
# Commands: 
# p, pick = use commit 
# r, reword = use commit, but edit the commit message 
# e, edit = use commit, but stop for amending 
# s, squash = use commit, but meld into previous commit 
# f, fixup = like "squash", but discard this commit's log message 
# x, exec = run command (the rest of the line) using shell 
# 
# These lines can be re-ordered; they are executed from top to bottom. 
# 
# If you remove a line here THAT COMMIT WILL BE LOST. 
# 
# However, if you remove everything, the rebase will be aborted. 
# 
# Note that empty commits are commented out 

对于那些想知道为什么我不只是编辑的文件,并将它们重新添加到提交,或什么的,我有不正确的作者信息,只有我纠正我有后运行“git commit”,并在我提交消息打开进行编辑时更改了作者信息。

也许我可以尝试删除整个.git文件夹或其他东西,但我更喜欢更优雅的方式。

另外,如果我不删除整个.git文件夹,我保留我的钩子和东西,我有一种感觉,这类问题的答案会说明Git中的基本设计原则,我可能还不了解。

+1

如果您对单一个人进行欺骗,则仅在您的回购协议中提交。你能不能使用'git commit --amend'?我很可能误解你的问题的基础。 – castis

回答

3

您可以变基上的--root顶部:

git rebase -i --root 

要简单地改变笔者对最后提交,使用此:

git commit --amend --no-edit --author="The Name <[email protected]>" 
+0

//,'git commit --amend --no-edit --author =“...','Twerked,在项目的顶层目录中输入如下:'$ git commit --amend --no-edit --author =“Nathan Bassanese <[email protected]>”'然而,'git rebase -i --root',不是那么多。在我删除了交互式rebase的提交之后,它仍然存在。 –

+0

//,当我尝试删除交互式rebase中的提交行后,我尝试应用“fixup”,以查看是否会以某种方式删除日志条目:'[vagrant @ localhost vagrant] $ git rebase -i --root' 'Can not 'fixup'without ...'但是它失败了,无论如何,感谢你的深思熟虑的答案,但我不认为我可以,良心良知,将它标记为已接受,直到我可以成功测试它为止。 –

+0

//值得注意的是,带有'--amend'和'--author'标志的'git commit'命令在一个分支中改变了提交,但是在另一个分支中没有提交。在每个分支上都有它。 –

2

我看你已经通过固定的机制工作一个特别的问题。

我会尽量满足你的更普遍的问题,但:

...我有回答到这类问题将在GIT中的基本设计原则说话,我可能还不明白的感觉。

这里是涉及这个特定过程的所有棘手的位。

  1. 名称(如master)是指向一个特定可动提交的指针。
  2. 每个提交指向其父提交。 A 提交,根据定义,没有父项。 (这里没有,但是有关需要了解的:一个合并提交被简单地定义为任何有至少两个家长提交。)
  3. 要创建任何承诺,我们需要一个分支,但创建一个提交,其中没有父,我们需要让分支没有提交 - 但看到点#1:分支名称指向提交。
  4. 工作衍合做重复git cherry-pick操作,从--onto目标生长的匿名分支。通过版本比较提交反对(一旦重复樱桃采摘完成后,新的匿名分支的顶端承诺取代了原来的分支的顶端承诺,即我们重新点的分支新的提示。)
  5. git cherry-pick作品其家长。例如,如果父文件有三个文件,并且提交的文件有四个文件,则提交文件会添加一个新文件。如果三个结转文件中只有一个是不同的,那么在该文件中改变的任何内容都会构成该提交的其余部分(呃,提交的作者和其他元数据也是如此:这些文件也在cherry-挑)。说完转身原来提交到一组更改,Git的然后应用相同改变一些其他(已经存在的)承诺,使新提交了这一点。新提交的父代是另一个提交。

这些原则创建Gordian knot that --root slices through。值得注意的是,--root在Git 1.6.2版本中是新的,并且在1.7.12中进行了大量修改(我隐约记得在此之前使用rebase并遇到一些问题)。

Git总是必须解决#1和#3之间的紧张关系(当git checkout增长--orphan选项时,解决方案本身得到了改进,并且在某个时候正确地形式化了)。这里的技巧是,在所谓的“未出生的分支”的时候,在Git的HEAD照常记录当前分支,但保留本身未创建的分支名。 (这里有助于了解 - 尽管这是一个你不应该担心的实现细节 - 分支指针当前存储在两个地方中的一个或两个地方,Git存储这些名称到ID的映射在.git/refs/和/或一个纯文本文件,.git/packed-refs小的单个文件。如果一个分支名称既不符合的地方,但HEAD,Git会认为这是“未出生的分支”。)

当进行新的提交,如果当前状态是“在未出生的分支”,Git会进行一次根提交。新的提交ID成为现在创建的分支的ID,我们现在摆脱了分支上的自相矛盾的状态,但没有提交。

我们仍然有问题git cherry-pick是通过比较提交给其父。这就是为什么,如果你想摘樱桃合并提交,你必须指定其中父:合并是具有两个或更多的家长提交,因此目前尚不清楚哪一个diff的反对。但是,一个根提交和它的所有零计数 - '零 - 零的父母呢?

Git通过比较樱桃采摘的根提交和the empty tree来解决此特定问题。由于空树是空的,所以每个文件都是新添加的,这对于樱桃挑选来说是正确的结果。

因此,为了与--root重新绑定,我们想创建一个孤立分支,然后樱桃挑选根提交,然后照常提交所有其他提交。但git rebase使用匿名分支。创建孤立分支的唯一正常方式是名称,但是rebase使用“分离HEAD”模式。而且,包括第一个选项在内的每个选项都需要对现有的提交进行更改,但为了创建新的根提交,我们必须避免使用一些现有的父项。

这个棘手的内部是在this answer from VonC找到(间接),其中链接到this commit to the Git code。 rebase脚本创建一个真正空的根提交(使用空树和内部“plumbing”命令创建一个具有用户指定的父ID的提交对象),然后生成一个内部“压扁”操作以挑选现有的根提交(用樱桃选择区别于同一棵空树)并将其与虚拟空根提交结合使用。

(这也有助于注意到,重订时的“南瓜”操作是指“修订之前的承诺”,一拉git commit --amend--amend操作告诉git commit作出新的承诺,现有一个不能改变的,但使新的提交的父母匹配现有提交的父母,这样做会影响旧的提交:分支现在指向新的提交,它指向“已修改”提交的父对象,修改后的提交仍然存在在存储库中,但除非有其他方法可以找到它,否则不再可见。)

(这两步技巧意味着作者信息是专门处理的。)


对于本权利要求的目的,至少,在分离的HEAD模式是(git checkout hashgit checkout --detach branchname后,例如)计数为在其它特殊的匿名分支,其尖端是当前提交的散列。

+0

//当我睡得更久时,我会阅读这篇文章,但我的第一印象是,除去“第一次”提交的困难来自上面第1点和第3点之间的矛盾。感谢您将“空树”引起我的注意,并提出深思熟虑的答案。 –

+2

Git通过不让分支指针移动直到出现替换提交,即从未真正删除第一次提交,从而“解决了”。 (事实上​​,除了'git gc'和它的管道之外,git从不删除*任何提交或任何其他对象,它是围绕*添加新东西*构建的,并且不会对任何现有对象进行更改。 ),当计划从现有的提交'E'开始并添加新的挑选提交时,并且您的第一个选择结果应该是无父项的,但是您有问题。 :-) – torek

+0

//,我想一个确定的答案,我是否可以,确实,删除第一次提交将是一个坚实的“不”,然后呢? –

相关问题