Git 在迭代上游开发中变基

Git rebase in developing with an iterative upstream

Git rebase 对我来说是获得线性历史的好方法,但最近我对它的行为有点困惑。情况是我有我的本地仓库,我在 GitLab 上的原始仓库和我课程的只读上游仓库。

基本上助教们在上游repo 发布文档和代码,我获取它并合并到我的repo,然后完成实验室。这是一个迭代的过程,因为lab2是在我完成lab1并将其推入origin之后发布的。令人困惑的事情发生在这个迭代中。

lab3 发布后,我将 master(其中包含我的 lab1 和 lab2 的代码)重新定位到 upstream/master,结果发现我的提交都集中在 [= 的最新位置46=]历史,如:

lab1-TA-release -> lab2-TA-release -> lab3-TA-release -> lab1-my-code(带变基时间)-> lab2-my-code(带变基时间)

我认为是提交时间显示了我的工作轨迹,所以我想看到的是线性历史,如:

lab1-TA-release -> lab1-my-code -> lab2-TA-release -> lab2-my-code -> lab3-TA-release

有什么办法可以实现我的愿望吗?

-----更新-----

例如,现在我已经完成了 lab2,lab3 已经在 upstream/master 上发布了。 lab3-TA-release 不在我本地的 master 上(所以我不能简单地使用 rebase 求助于我的 master)。我需要先git rebase upstream/mastermy lab2-my-codelab1-my-code就是在这里聚在一起,焕然一新。所以真正的提交时间(当我完成我的工作时)消失了,我很困惑。

有没有办法自动保留提交的原始时间(即实时)并使其线性化?

如果lab2-TA-releaselab1-my-code提交之间没有冲突,你可以做git rebase -i HEAD~4(不需要是4,但可能是4你的情况。)并简单地更改提交的顺序。

例如,当您 运行 git rebase -i HEAD~4 时,您应该会看到类似这样的内容:

pick <hash4...> Lab 2 released.
pick <hash3...> Lab 1 finished.
pick <hash2...> Lab 2 finished.
pick <hash1...> Lab 3 released.

# Rebase ...
# ...

然后你可以简单地通过剪切和粘贴来切换顺序:

pick <hash3...> Lab 1 finished.
pick <hash4...> Lab 2 released.
pick <hash2...> Lab 2 finished.
pick <hash1...> Lab 3 released.

# Rebase ...
# ...

我想如果你只关心本地仓库的提交时间线,那么它应该保留重新排序后提交的原始时间。

但是,当您要将更改推送到远程仓库时,您可能必须 git push --force 因为否则在推送新更改之前您可能会被要求先 git pull,即可能不是您想要的,因为您似乎希望您的本地提交时间轴看起来很直,而不是在您的提交历史记录图中发生任何合并?

只是当你git push --force时,它不会改变本地提交的原始时间,而是将远程仓库中提交的时间更改为你推送的时间。

也许你可以尝试创建一个临时分支并测试它,看看它是什么样子。

$ git checkout -b temp
$ git push -u origin temp
$ git rebase -i HEAD~n # Replace n with an appropriate number and reorder the commits. It should be successful if there isn't any conflict.

当您 git status 时,您应该会看到以下消息:

On branch temp
Your branch and 'origin/temp' have diverged,
and have n and n different commits each, respectively.
  (use "git pull" to merge the remote branch into yours)

nothing to commit, working tree clean

所以你 git push --force,当你 git log --pretty=format:'%h %ad | %s%d [%an]' --graph --date=rfc2822 时,你应该看到带有原始时间戳的直接提交历史记录。

您还可以查看远程存储库的提交时间表,看看它是什么样子。

我明白了!

我做的测试都是错误的方向。我想回答我自己的问题并给路过的人一些信息。

假设我已经完成了 lab2 并且 lab3 已经在 upstream/master 上发布了。 lab3-TA-release 不在我本地的 master 上。

首先是

$ git fetch upstream/master
$ git checkout upstream/master

而现在HEAD是分离的,只是运行

$ git rebase master

rebase upstream/mastermaster

然后重要的是通过创建一个新的临时分支来保存更改,因为 HEAD 是分离的。如果您只是结帐到其他分支,更改将消失。

$ git branch temp
$ git checkout master
$ git merge temp

merge 将是 fast-forward,一切就绪。

然后只需删除 temp 分支

$ git branch -d temp