DEV Community

JayZho
JayZho

Posted on

Working with Git: a practical guide

Some basic understandings

  • You need to well distinguish the concepts of the local repo and the remote repo. There are basically two separate repo. Each developer has their local repo, while the remote repo sitting on github acts like a single globalised repo. The interaction between a local repo and the remote repo is done via commands like git push, git fetch, etc.
  • Each branch has a HEAD, which is just a pointer to a commit that marks the tip of the branch. A branch is basically just a pointer to a commit and its commit history.

Fetch vs. Pull

To put it simple: git pull = git fetch + git merge
git fetch refreshes the local view of the remote repo to keep it up-to-date with all the newest changes in the remote repo. Notice the phrase "local view of the remote repo", it means that this action only let us know the current status of the remote repo, without changing(merging to) the local repo.
To merge the changes in any of the remote branches into our local branch, do git merge origin/<remote_branch>.

Working with branches

List all branches

To list all local branches and the branch you're on locally: git branch
To list all remote branches: git branch -r

Create a local branch

Create another local branch: git branch <branch_name>
Checkout to a local branch: git checkout <branch_name>
Create and checkout to a local branch: git checkout -b <branch>
Create a branch from another local branch and checkout to it: git checkout -b <new_branch> <from_branch>

Checkout to a remote branch

For git checkout <branch_name>, if there exists a remote branch with , git will

  1. create a local branch with the same name as
  2. checkout to this local branch
  3. make this branch track

The purpose of "making a branch track a remote branch" is that when using implicit commands like git pull, git push or git merge, git knows which remote branch you're refering to. Otherwise it will say something like "no tracking information for the current branch".

To set the remote branch to track, use the command
git branch --set-upstream-to=origin/<remote_branch> <local_branch>

Notice that once this is done, the command git checkout <remote_branch> no longers set the local branch to track the remote branch , instead it stays tracking the remote branch specified in the previous --set-upstream-to command.

Create remote branch from the local branch

Checkout to a branch that you only have locally:
git checkout local1
Assuming that you've commited successfully, run the command:
git push origin local1
This will create a new remote branch named "local1", and push to it. Notice that it does not set the local branch to track the remote branch "local1".

Push to a different remote branch

Say you're in local branch "local1", doing git push origin main will push from local branch "main" to the remote branch "main". (So nothing to do with the branch you're currently in)
If you wanna push from local branch "local1" to a remote branch "remote", you can do git push origin local1:remote.

Integrating different works

The mechanism

Let's say we're on a feature branch and we wanna merge the main branch into this feature branch.
Before merging main into feature, git first determines the 3 commits that are: the base of the two branches, the tip(current commit) of branch "main", the tip(current commit) of branch "feature".
Image description
Then git will grab everything new from the newest commit(known as the tip) in branch "main" and chuck it into the tip of branch "feature", making this resultant repo a new commit on top of the previous commit in branch "feature".

If the branch "feature" has no newer commits after the common "base" commit, git simply makes the tip of branch "main" the new merge commit of branch "feature", known as a "fast forwarding" merge commit. And yes, the tip of a branch is nothing but a pointer to a commit, so in this case, git just let the tip of branch "feature" point to the same commit as the tip of "main", making this the "new" merge commit as the result of git merge feature main.

Merge from a branch

If you're already on branch A, then to merge branch B into branch A: git merge <branch_B>
Merge 2 branches explicitly: git merge <receiving_branch> <incoming_branch>
If the merge results in a conflict and you wanna abandon this merge action and roll back to the state before this merge, do git reset --hard HEAD.

Rebase to a branch

Rebase moves all the commits in one branch on top of another branch, making a single-line commit history. This is another technique used in merging different commits, and has advantages over git merge in the sense that it creates a linear branch history instead.

Top comments (0)