rqiu.dev

A concise summary of all you need to know about Git, maybe

Last week I was asked a question:

Have you ever messed up a local git repo and decided to delete everything clone from remote again?

Yeah, I did. I guess, a lot of us sitting in that room had this typical experience especially when we were at the stage where we thought we know about Git, but definitely not ever close to “master” it.

To cross it off my backlog, I followed an interactive tutorial on Learn Git Branching. And hopefully I can summarize all the key takeaways concisely enough for anyone on the same boat. Just a reminder that I assume we are both quite familiar with git basics and intend to leave StackOverflow for our next teamwork project when people are doing some real collaboration.

git-xkcd

It is said that 98% of job applicants with a ‘Git’ in skill section are only using git add, git commit and git push. (I made this up, but I bet the reality is not far from this.)

1. Branching on main (locally)

Branches and merges

git checkout -b bugFix
git commit
git checkout main
git commit
git checkout bugFix
git rebase main

Moving around in commit trees

Moving work around

      A---B---C topic
     /
D---E---F---G main

git rebase main topic

              A'--B'--C' topic
             /
D---E---F---G main

git checkout main -b topic_new
git cherry-pick A^..C

      A---B---C topic
     /
D---E---F---G master
             \
              A'--B'--C' topic_new

A side quest on git squash

This is something else I would like to address with some past struggles. We should never take it for granted like git squash is supposed to squashing everything together easily. A good tutorial I came across earlier should be helpful:

Goal: to merge multiple commits into one with the help of git rebase -i.

What we have:

871adf OK, feature Z is fully implemented      --- newer commit --┐
0c3317 Whoops, not yet...                                         |
87871a I'm ready!                                                 |
643d0e Code cleanup                                               |-- Join these into one
afb581 Fix this and that                                          |
4e9baa Cool implementation                                        |
d94e78 Prepare the workbench for feature Z     -------------------┘
6394dc Feature Y                               --- older commit

What we want to have:

84d1f8 Feature Z                               --- newer commit (result of rebase)
6394dc Feature Y                               --- older commit
  1. Choose starting commit: git rebase -i HEAD~7 (7 commits before HEAD). If we decide not to count the commit number, we can use hash 6394dc instead with git rebase -i 6394dc. This can be translated to “merge all commits on top of commit 6394dc”.
  2. Picking and squashing. At this point, the selected commits are collected in a reverse order.
pick d94e78 Prepare the workbench for feature Z     --- older commit
pick 4e9baa Cool implementation
pick afb581 Fix this and that
pick 643d0e Code cleanup
pick 87871a I'm ready!
pick 0c3317 Whoops, not yet...
pick 871adf OK, feature Z is fully implemented      --- newer commit

[...]
  1. Be aware of the reverse order.
  2. Replace `pick` with `squash` or `s` for squashable commits.
  3. Save and close the temp file.
  1. Create a new commit. The editor will pop up again with a default message: a list of all the intermediate commits. We can edit it to be more meaningful.

A mixed bag

A bunch of more complex scenarios where you need to move commits around either by moving single commit or juggling multiple commits (while this can be achieved by either git rebase -i or git cherry-pick).

Advanced topics

Begin:

c0---c1---c2---c3---c4---c5   main*
      one
      two
      three

End:

      three
      c2---c3---c4---c5   main
      /
c0---c1---c4'---c3'---c2'   one
      \
      c5'---c4''---c3''---c2''   two*

Solution:

git checkout one
git cherry-pick c4 c3 c2
git checkout two
git cherry-pick c5 c4 c3 c2
git rebase c2 three

2. Branching on remote

Push, pull, remotes

git checkout -b feature HEAD
git push origin feature
git checkout main
git reset HEAD^

I’ve left the last part of the tutorial “Advanced git remote” unfinished, highly recommend you to give it a go at your own pace. The animated commit tree is really intuitive.

#git