为什么我的提交历史记录是这样的,我该如何修复它?

时间:2016-06-27 22:14:59

标签: git git-merge git-rebase

所以在过去的几天里,我一直试图弄清楚为什么我的git提交历史看起来像这样,我的提交历史不是像我希望的那样是线性的?我尝试了很多东西试图让所谓的扁平化,但无济于事。

如果有人可以提供帮助,那将非常感激。

从git bash中的git log --oneline --graph命令查看

view 1

SmartGit

中查看git log

view 2

以下是我运行git rebase 0fa9983894820ac8062a7413188e4ea2bc28089b

后出现的错误

error

3 个答案:

答案 0 :(得分:3)

看看我丑陋的树:

* 8d61057 (HEAD -> master) file4
*   61795ae Merge branch 'new'
|\  
| * 56f104d file2
* | 2484695 file3
|/  
* ecc3f4f init

请注意61795ae Merge branch 'new'没有引入任何新内容,但仅仅是合并提交。

我可以在分割前的最后一次提交中使用rebase直线回到我的主干。

git rebase ecc3f4f

现在树再次直了

* e794681 (HEAD -> master) file4
* b65595a file3
* 3d6ffe9 file2
* ecc3f4f init

解释

克隆项目后,我想查看提交以查看冲突。

您重命名了此备份脚本。

051dae3 Rename backup final ftp.py to backup ftp v.4 (final).py
Backup scripts/backup final ftp.py → Backup scripts/backup ftp v.4 (final).py

但同时在此存储库的另一个副本中,您将此备份脚本移动到了#34; Python"与一组其他人的文件夹

09abfd7 Renamed some of the files
Backup scripts/backup final ftp.py → Python/Backup scripts/backup final ftp.py

现在要解决这个冲突,你必须用两次提交来清理它。

第一个只是将文件从正确的文件夹中取出到具有正确名称的错误文件夹。

8006e70 Renamed some files
Python/Backup scripts/backup final ftp.py → Backup scripts/backup ftp v.4 (final).py

然后你刚用"不需要的文件夹"

丢失了该文件
bac2105 Deleted an unneeded folder
deleted Backup scripts/backup ftp v.4 (final).py

基本上,这是一个检查这两个提交的问题,将它们轻轻地重置到暂存区域,并将它们全部集中在一起。

然后樱桃挑选剩下的。您可以克隆straight master branch here

程序

git clone https://github.com/Lowe-Man/Portfolio

cd Portfolio/

git log --graph --oneline --decorate --all
* de71d41 (HEAD -> master, origin/master, origin/HEAD) Removed a gitignore specifier from the .gitignore file
* f80eb5c Added 'Lecture 26 Files'
* 505478e Added 'Lecture 25 Tuples'
* 632a2f3 Added 'Lecture 23 Dictionaries'
* 990d74e Reorganized/Fixed all of the code/comments on all of the lectures that I have done up to this point
* bb213ac Added 'Lecture 21 Lists'
* ab99b1c Added 'Lecture 19 Print Formatting'
* 3f37ca3 Changed the numbering of the files
* 16e17be Added 'Lecture 16 Strings'
* c654494 Reorganized the repository
* 60b17e4 Added 'Remove Numbers v.1.py'
* e35b6ba Added 'Lecture 14 Numbers'
* bac2105 Deleted an unneeded folder
*   8006e70 Renamed some files
|\  
| * 051dae3 Rename backup final ftp.py to backup ftp v.4 (final).py
* | 09abfd7 Renamed some of the files
|/  
* 0fa9983 Everything is in working order
* dfc9747 Fixed a few if statements
* e183900 Added Countdown Timers and other help to the portfolio
* 2377980 Removed some unnecessary lines of code
* 4172115 Added some new fetures to the script
* 4a7f2d1 Fixed some minor bugs in the code
* 589251c Removed text from a variable
* 93e9742 Finished the backup final ftp script for now
* c5687a3 Added the feature to remove files/folders that are older than a certain age
* 19a495f Removed some blank lines at the bottom of the file
* c2c58c3 Converts the folder to a .tar.bz2 and then deletes the folder
* 6718968 Made some minor changes to the code to increase usability
* b7d6608 Initial commit
git checkout 051dae3

git reset --soft HEAD~

git status
HEAD detached from 051dae3
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

  renamed:    Backup scripts/backup final ftp.py -> Backup scripts/backup ftp v.4 (final).py
git checkout 09abfd7

git reset --soft HEAD~

git status
HEAD detached from 09abfd7
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

  new file:   Backup scripts/backup ftp v.4 (final).py
  renamed:    Backup scripts/backup final ftp.py -> Python/Backup scripts/backup final ftp.py
  renamed:    Backup scripts/backup ftp v.1.py -> Python/Backup scripts/backup ftp v.1.py
  renamed:    Backup scripts/backup ftp v.2.py -> Python/Backup scripts/backup ftp v.2.py
  renamed:    Backup scripts/backup ftp v.3.py -> Python/Backup scripts/backup ftp v.3.py
  new file:   Python/Backup scripts/backup local.py
  renamed:    Countdown Timers/Countdown Timer (Cleaned).py -> Python/Countdown Timers/Countdown Timer v.2.py
  new file:   Python/Countdown Timers/Countdown Timer v.3 (final).py
  renamed:    Countdown Timers/Coutdown Timer.py -> Python/Countdown Timers/Coutdown Timer (original).py
  renamed:    Countdown Timers/Coutdown Timer (Improved).py -> Python/Countdown Timers/Coutdown Timer v.1.py
  renamed:    Help/How to remove zeros.py -> Python/Help/How to remove zeros.py
  renamed:    Help/Timezone.py -> Python/Help/Timezone.py
  renamed:    Countdown Timers/length.py -> Python/Help/length.py

抛弃额外的副本,并将正确命名的副本移到Python文件夹中。

rm 'Python/Backup scripts/backup final ftp.py'

mv 'Backup scripts/backup ftp v.4 (final).py' 'Python/Backup scripts/backup ftp v.4 (final).py'

git add .

git status
HEAD detached from 09abfd7
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

  renamed:    Backup scripts/backup ftp v.1.py -> Python/Backup scripts/backup ftp v.1.py
  renamed:    Backup scripts/backup ftp v.2.py -> Python/Backup scripts/backup ftp v.2.py
  renamed:    Backup scripts/backup ftp v.3.py -> Python/Backup scripts/backup ftp v.3.py
  renamed:    Backup scripts/backup final ftp.py -> Python/Backup scripts/backup ftp v.4 (final).py
  new file:   Python/Backup scripts/backup local.py
  renamed:    Countdown Timers/Countdown Timer (Cleaned).py -> Python/Countdown Timers/Countdown Timer v.2.py
  new file:   Python/Countdown Timers/Countdown Timer v.3 (final).py
  renamed:    Countdown Timers/Coutdown Timer.py -> Python/Countdown Timers/Coutdown Timer (original).py
  renamed:    Countdown Timers/Coutdown Timer (Improved).py -> Python/Countdown Timers/Coutdown Timer v.1.py
  renamed:    Help/How to remove zeros.py -> Python/Help/How to remove zeros.py
  renamed:    Help/Timezone.py -> Python/Help/Timezone.py
  renamed:    Countdown Timers/length.py -> Python/Help/length.py

除了我们重命名的其他内容之外,感兴趣的分阶段解决方案是:

  renamed:    Backup scripts/backup final ftp.py -> Python/Backup scripts/backup ftp v.4 (final).py

使用相同的消息进行新的提交。

git commit -c ORIG_HEAD

git log --graph --oneline --decorate --all
* 1cc1b2c (HEAD) Renamed some of the files
| * de71d41 (origin/master, origin/HEAD, master) Removed a gitignore specifier from the .gitignore file
| * f80eb5c Added 'Lecture 26 Files'
| * 505478e Added 'Lecture 25 Tuples'
| * 632a2f3 Added 'Lecture 23 Dictionaries'
| * 990d74e Reorganized/Fixed all of the code/comments on all of the lectures that I have done up to this point
| * bb213ac Added 'Lecture 21 Lists'
| * ab99b1c Added 'Lecture 19 Print Formatting'
| * 3f37ca3 Changed the numbering of the files
| * 16e17be Added 'Lecture 16 Strings'
| * c654494 Reorganized the repository
| * 60b17e4 Added 'Remove Numbers v.1.py'
| * e35b6ba Added 'Lecture 14 Numbers'
| * bac2105 Deleted an unneeded folder
| *   8006e70 Renamed some files
| |\  
| | * 051dae3 Rename backup final ftp.py to backup ftp v.4 (final).py
| |/  
|/|   
| * 09abfd7 Renamed some of the files
|/  
* 0fa9983 Everything is in working order
* dfc9747 Fixed a few if statements
* e183900 Added Countdown Timers and other help to the portfolio
* 2377980 Removed some unnecessary lines of code
* 4172115 Added some new fetures to the script
* 4a7f2d1 Fixed some minor bugs in the code
* 589251c Removed text from a variable
* 93e9742 Finished the backup final ftp script for now
* c5687a3 Added the feature to remove files/folders that are older than a certain age
* 19a495f Removed some blank lines at the bottom of the file
* c2c58c3 Converts the folder to a .tar.bz2 and then deletes the folder
* 6718968 Made some minor changes to the code to increase usability
* b7d6608 Initial commit

现在我们已将提交051dae38006e70bac2105有效地合并到09abfd7作为新提交1cc1b2c,这就是我的方式认为它应该首先在功能上得到承诺。

所以剩下的就是从e35b6ba Added 'Lecture 14 Numbers'开始挑选树的其余部分

git cherry-pick e35b6ba^..de71d41

git log --graph --oneline --decorate --all
* 0e52036 (HEAD) Removed a gitignore specifier from the .gitignore file
* 1cf948b Added 'Lecture 26 Files'
* 62a1602 Added 'Lecture 25 Tuples'
* aeb7421 Added 'Lecture 23 Dictionaries'
* d47635d Reorganized/Fixed all of the code/comments on all of the lectures that I have done up to this point
* d54141c Added 'Lecture 21 Lists'
* 66174f2 Added 'Lecture 19 Print Formatting'
* 3969da2 Changed the numbering of the files
* 9c4828c Added 'Lecture 16 Strings'
* ce159a3 Reorganized the repository
* 759e08b Added 'Remove Numbers v.1.py'
* 323be27 Added 'Lecture 14 Numbers'
* 1cc1b2c Renamed some of the files
| * de71d41 (origin/master, origin/HEAD, master) Removed a gitignore specifier from the .gitignore file
| * f80eb5c Added 'Lecture 26 Files'
| * 505478e Added 'Lecture 25 Tuples'
| * 632a2f3 Added 'Lecture 23 Dictionaries'
| * 990d74e Reorganized/Fixed all of the code/comments on all of the lectures that I have done up to this point
| * bb213ac Added 'Lecture 21 Lists'
| * ab99b1c Added 'Lecture 19 Print Formatting'
| * 3f37ca3 Changed the numbering of the files
| * 16e17be Added 'Lecture 16 Strings'
| * c654494 Reorganized the repository
| * 60b17e4 Added 'Remove Numbers v.1.py'
| * e35b6ba Added 'Lecture 14 Numbers'
| * bac2105 Deleted an unneeded folder
| *   8006e70 Renamed some files
| |\  
| | * 051dae3 Rename backup final ftp.py to backup ftp v.4 (final).py
| |/  
|/|   
| * 09abfd7 Renamed some of the files
|/  
* 0fa9983 Everything is in working order
* dfc9747 Fixed a few if statements
* e183900 Added Countdown Timers and other help to the portfolio
* 2377980 Removed some unnecessary lines of code
* 4172115 Added some new fetures to the script
* 4a7f2d1 Fixed some minor bugs in the code
* 589251c Removed text from a variable
* 93e9742 Finished the backup final ftp script for now
* c5687a3 Added the feature to remove files/folders that are older than a certain age
* 19a495f Removed some blank lines at the bottom of the file
* c2c58c3 Converts the folder to a .tar.bz2 and then deletes the folder
* 6718968 Made some minor changes to the code to increase usability
* b7d6608 Initial commit

现在我们可以删除旧的主分支,将此分支用作新主分支,并强制推送到远程分支。

git branch -d master

git checkout -b master

git push origin master --force

git log --graph --oneline --decorate --all
* 0e52036 (HEAD -> master, origin/master, origin/HEAD) Removed a gitignore specifier from the .gitignore file
* 1cf948b Added 'Lecture 26 Files'
* 62a1602 Added 'Lecture 25 Tuples'
* aeb7421 Added 'Lecture 23 Dictionaries'
* d47635d Reorganized/Fixed all of the code/comments on all of the lectures that I have done up to this point
* d54141c Added 'Lecture 21 Lists'
* 66174f2 Added 'Lecture 19 Print Formatting'
* 3969da2 Changed the numbering of the files
* 9c4828c Added 'Lecture 16 Strings'
* ce159a3 Reorganized the repository
* 759e08b Added 'Remove Numbers v.1.py'
* 323be27 Added 'Lecture 14 Numbers'
* 1cc1b2c Renamed some of the files
* 0fa9983 Everything is in working order
* dfc9747 Fixed a few if statements
* e183900 Added Countdown Timers and other help to the portfolio
* 2377980 Removed some unnecessary lines of code
* 4172115 Added some new fetures to the script
* 4a7f2d1 Fixed some minor bugs in the code
* 589251c Removed text from a variable
* 93e9742 Finished the backup final ftp script for now
* c5687a3 Added the feature to remove files/folders that are older than a certain age
* 19a495f Removed some blank lines at the bottom of the file
* c2c58c3 Converts the folder to a .tar.bz2 and then deletes the folder
* 6718968 Made some minor changes to the code to increase usability
* b7d6608 Initial commit

答案 1 :(得分:2)

通过提供您的源代码,我能够对您当前的回购执行以下步骤,并记住@jpaugh的答案,以获得与您开始时完全相同的代码。你遇到麻烦的原因 @jpaugh的答案是因为我们已经删除/删除了我们必须手动解决的合并冲突。

因为您已经解决了这个合并冲突,所以我们将完全按照您的第一次解决方案来做。

抓住你想改变历史的分支。

git checkout origin/master

我们将rebase提交合并之前的提交。默认情况下,rebase不会保留合并历史记录,因此这会将您的工作从该提交线性重放到您的origin / master所在的位置。

git rebase 0fa9983

但是我们有一些问题。历史记录中的合并具有您已解决的删除/删除冲突。让我们添加您在解析提交8006e70和分支051dae3中所做的更改,以模仿您在另一个分支之后立即创建它们,而不是并行。

git checkout 8006e70 Backup\ scripts/backup\ ftp\ v.4\ \(final\).py
git rm Backup\ scripts/backup\ final\ ftp.py
git rm Python/Backup\ scripts/backup\ final\ ftp.py

所以现在我们要将更改作为新提交提交,但是让我们使用C标记为它提供与我们要替换的合并提交相同的提交消息。使用我们想要消息的分支的哈希值。

git commit -C 051dae3

让我们使用continue命令继续变基。

git rebase --continue

我们遇到了一个新问题,那就是我们将两个提交合并为一个(合并和分支)。它仍然试图在延续篮板方面发挥作用。如果我们使用-i标记用于我们的原始rebase命令,我们可以指出我们应该跳过此提交,但这个示例是所有命令行。我们将在这里跳过它。它失败了,因为它所做的所有更改都已经发生。我们选择在分支中提交提交消息,而不是简短的renamed some files消息,因此当您查看我们的新历史时,您的意图是明确的。继续并跳过这个冲突,让rebase继续历史的其余部分。

git rebase --skip

我们不再有任何变相了。该功能已退出。现在我们有一个具有线性提交历史记录的分离头。让我们检查一下我们是否成功重建历史记录,但保持文件不变。

git diff origin/master

最后一个差异显示您的文件没有变化,只有历史记录。 这产生以下历史:

$ git log --oneline --graph
* e8eec78 Removed a gitignore specifier from the .gitignore file
* 2d51522 Added 'Lecture 26 Files'
* 93f6908 Added 'Lecture 25 Tuples'
* 2b3d9c5 Added 'Lecture 23 Dictionaries'
* a8bcfaa Reorganized/Fixed all of the code/comments on all of the lectures that I have done up to this point
* f3d0448 Added 'Lecture 21 Lists'
* 7ce1af4 Added 'Lecture 19 Print Formatting'
* 740f459 Changed the numbering of the files
* da6f679 Added 'Lecture 16 Strings'
* 2d4abf6 Reorganized the repository
* 1d88453 Added 'Remove Numbers v.1.py'
* 85cda36 Added 'Lecture 14 Numbers'
* 3d89d1a Deleted an unneeded folder
* bc41dc6 Rename backup final ftp.py to backup ftp v.4 (final).py
* 52a1354 Renamed some of the files
* 0fa9983 Everything is in working order
* dfc9747 Fixed a few if statements
* e183900 Added Countdown Timers and other help to the portfolio
* 2377980 Removed some unnecessary lines of code
* 4172115 Added some new fetures to the script
* 4a7f2d1 Fixed some minor bugs in the code
* 589251c Removed text from a variable
* 93e9742 Finished the backup final ftp script for now
* c5687a3 Added the feature to remove files/folders that are older than a certain age
* 19a495f Removed some blank lines at the bottom of the file
* c2c58c3 Converts the folder to a .tar.bz2 and then deletes the folder
* 6718968 Made some minor changes to the code to increase usability
* b7d6608 Initial commit

请注意提交哈希值是如何更改的?这是因为历史发生了变化。如果要将其传播回原点/主文件,则需要强制它。这是因为如果历史记录哈希值不匹配,则推送失败,我们只是更改了大部分历史哈希值。

如果要在上游传播这些更改,请执行git push --force origin/master

请记住,如果其他人面向公众,他们可以分叉您的遥控器,并且如果其他人可以访问这些提交,最好不要更改git历史记录。

$ git --version
git version 2.9.0

答案 2 :(得分:1)

您的历史记录是这样的原因是因为您在某个时刻创建了一个新分支,然后将其合并回来。(或其他人做过。)

如果您正在使用GitHub,那么它也可能意味着您接受了一个拉取请求,这相当于合并。如果是这样,通常无法解决这个问题,一般情况下。从他们的角度来看,这是一个合理的选择,因为合并比变基更强大,并且更好地保留了作者身份的变化:我们只需要接受更丑陋的日志输出。在这种情况下,你可以在这里停止阅读。

我不知道改变这种情况的自动方式,但我可以向您展示如何rebase您的提交方式。这涉及从错误一直到HEAD重写历史记录,创建具有相同内容的不同提交。

但是,我注意到您正在查看的分支不是本地分支,而是本地副本的原始分支(假设此处通常采用Git约定)。我理解对清洁和漂亮的日志输出的渴望,但是,有一个实际的理由不能改变旧的历史:

  

警告:虽然可以在本地提交提交,但将此类更改推送到公共项目并不是一个好主意。重新定位您的历史记录会给与您共享未经修改的历史记录的其他人带来问题。所以,参与你项目的任何其他人都会受到冲击。

有了这个警告,请点击:

  1. 首先,制作存储库的副本,以便备份。 (rebase命令永远不会丢失数据,但如果您不熟悉rebase命令,如果您犯了错误或改变主意,很难回到已知状态。)
  2. 根据origin/master查看新分支,因为您无法直接修改(git checkout -b new-master origin/master
  3. 接下来,执行git rebase --interactive <commitish>,其中<commitish>标识标记为&#34的提交;所有内容都处于正常工作状态&#34; (0fa9)。
  4. 现在将在您的编辑器中打开rebase操作,以供您批准。
  5. 第一行将是一个名为&#34;重命名的一些文件&#34; (09ab)。将其操作从pick更改为edit
  6. 保存文件并关闭它。 rebase操作将开始。
  7. 当rebase在第一次提交后停止时,git cherry-pick <commitish>其中<commitish>描述提交名为&#34;将备份文件ftp.py重命名为...&#34;。
  8. git rebase --continue
  9. 验证结果。您会注意到,每个提交现在都有不同的ID,尽管具有相同的描述和相同的内容(差异)。这是因为您使用更改编写了历史记录。提交日期将更改,但不会更改作者日期。
  10. 现在,如果您想使用新历史记录对其他人进行攻击,可以将这些更改推送到origin存储库:

    $ git push --force origin/master
    

    --force是必需的,因为它会覆盖现有分支,并使从中创建的任何分支无效,包括所有贡献者的本地存储库。