Search code examples
gitrebaseupstream

Git rebase in developing with an iterative upstream


Git rebase for me is a good way to get a linear history, but recently I got a little confused of its behavior. The situation is that I have my local repo, my origin repo on GitLab and the read-only upstream repo of my course.

Basically TAs release documentations and codes in upstream repo, I fetch it and merge into my repo, and then finish the lab. It is an iterative process, for the lab2 is released after I finish lab1 and push it into origin. Things confusing happens in this iteration.

After lab3 was released, I rebased master (which contains my code for lab1 and lab2) onto upstream/master, only to find that my commits were all gathered together at latest location of git history, like:

lab1-TA-release -> lab2-TA-release -> lab3-TA-release -> lab1-my-code (with rebase time) -> lab2-my-code (with rebase time)

I think it is commits time that shows the track of my work, so what I'd like to see is a linear history like:

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

Is there any way to realize my wish?

-----update-----

For example, now I have finished lab2 and lab3 has been released on upstream/master. lab3-TA-release is not on my local master (so I cannot simply use rebase to resort my master). I need to git rebase upstream/master first. It is here that my lab2-my-code and lab1-my-code got gathered together and all refreshed with new time. So the real commit time (when I finished my work) disappear and I got confused.

Is there any way to automatically reserve original time (means the real time) of commits and make it linear?


Solution

  • I got it!

    The tests I have been made was all in wrong direction. I'd like to answer my own question and give anyone who passes by some information.

    Suppose that I have finished lab2 and lab3 has been released on upstream/master. lab3-TA-release is not on my local master.

    The first thing is

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

    And now HEAD is detached, simply run

    $ git rebase master
    

    to rebase upstream/master onto master.

    Then it is important to save changes by creating a new temporary branch, for HEAD is detached. If you just checkout to other branch, changes are gone.

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

    And the merge would be fast-forward, things all set.

    Then just delete temp branch by

    $ git branch -d temp