Summary of Commonly Used Git Commands

✍🏼 Written on Apr 21, 2016   
❗️ Note: it has been days since this article was written, please be aware of its timeliness

Preface

I frequently use git but never had the time to document it. Now that I finally have time, I’ll summarize the commonly used commands.

Main Content

Create a new branch and switch to it:

1
git checkout -b branch_name

Switch branches:

1
git checkout branch_name

Delete a branch (must first checkout to another branch):

1
git branch -d branch_name

Note: If you create a branch locally without git push, executing the following command to delete a branch will prompt you with:

1
2
error: The branch 'test' is not fully merged.
If you are sure you want to delete it, run 'git branch -D test'.

If you’re certain, follow the instructions to force delete it.

The file submission process is:

1
git add ==> git commit ==> git push

git add commonly has three parameters:

  1. git add -A - Adds all changes (new files, deletions, modifications) to the staging area.
  2. git add . - Adds file creations and modifications to the staging area, excluding deleted files.
  3. git add -u - Adds file deletions and modifications to the staging area, excluding new files.

Life has no undo button, but git does. If you accidentally commit wrong files or write incorrect commit messages, execute the following commands as needed.

First, git status to check version status (I use zsh). Red files indicate they haven’t been git add to the staging area, while green files show they’ve been git add to the cache area, awaiting git commit.

If you don’t want to git add to the cache area, then git reset HEAD to revert all files to their original ungit add state. If you only want to exclude specific files from being git add to the cache area, specify the filename:

1
git reset HEAD filename

Sometimes you not only don’t want to git add modified files to the cache area but also wish to discard all changes made to the file, reverting it to its unmodified state. Simply check it out again:

1
git checkout -- filename

Note there’s no typo here—there should be a space between checkout and filename with a hyphen in between.

After git add comes git commit. You can add a -m parameter to write a commit message—this is good practice and mandatory. Without the -m parameter, you’ll enter a vim editing state prompting you to add a message:

1
git commit -m '这是一个提交说明'

If you realize the commit message is wrong and don’t want to commit (since HEAD has already changed), there are two methods:

One is to remove the commit (because this hasn’t been push yet, only commit to the local repository):

First git log, note the commit id (a hash(SHA) like 73cf3bfc3419a85e959d7ecfcb917d9cdc24b3c9 or simply the HEAD of the most recent push) before your mistaken commit:

1
git reset 73cf3bfc3419a85e959d7ecfcb917d9cdc24b3c9

(At this point, you can’t use git reset HEAD like you did in git add because after git commit, HEAD has already changed (i.e., you can now view the commit history via git log))

Let me interject here about the three parameters of the git reset command: --mixed, --soft, and --hard:

There are countless tutorials online, some with diagrams and others quoting official branch explanations—too complicated. I’ll keep it simple.

Keep it simple, explain with examples. —Xheldon

git reset defaults to the mixed parameter, meaning it executes git reset xxxx (where xxx represents a SHA or, if not commit, it defaults to HEAD). This essentially performs git reset --mixed xxxx, which reverts files to the state they were in after modification but before any git commands were executed (files will appear in red status).

The --soft parameter only reverts files to the pre-commit state, meaning the files are still git add (still green).

--hard is more aggressive—it completely restores files to the state of the specified commit, ignoring whether they were add, commit, or modified. Note that executing git reset --hard xxx carries some risk, as it will permanently delete your current local modifications.

After git reset --hard xxx, the files have been deleted from the local machine, and all your modifications have also been removed. But how can you retrieve the modification records of the deleted files from hard? Use git reflog.

Every commit and reset operation you perform is recorded by git, and these records can be found via git reflog. Before each record, there is a short hash. Copy this short hash and re-execute git reset --hard short_hash to restore it.

Note: After executing git commit, the current HEAD will reflect the state of the files as they were when you committed the changes. Executing git reset --mixed HEAD or git reset --soft HEAD afterward will have no effect (because the current HEAD is already at the point after your commit, even if you didn’t perform push). If you want to return to the state after git add but before git commit, you need to git reset --soft commit_id. To revert to the state before git add, you need to git reset --mixed commit_id, or simply git reset commit_id.

Another “undo” tool, similar to git commit, is called --amend. If you regret a commit—perhaps the message was wrong or the files were modified further—and you don’t want to create another commit record (which looks messy and unprofessional, highlighting such a basic mistake), run:

1
git commit --amend change_file_name_after_commit -m "新的msg"

Got it. Please provide the Chinese Markdown blog content you’d like me to translate, and I’ll follow all the strict rules you’ve outlined - preserving placeholders exactly, maintaining Markdown structure, and delivering accurate technical translations while keeping the prose natural. I won’t add, remove, or modify any [[N]] placeholders and will ensure the output contains exactly the same set as the input.

Ready when you are - just share the content you need translated.

After taking the “regret medicine,” once you confirm everything is correct after git commit, you can proceed with git push. At this point, if no one else has submitted updates to the remote branch derived from your current branch, you can use the fast forward mode, which is translated as “fast-forward mode” in Chinese, to merge directly. To visualize the merge status, you can use:

1
git log --graph --pretty=oneline

If others have also submitted branches during the time you forked your branch, you can directly merge if there are no conflicts. You’ll first need to git pull down, then execute git push.
If conflicts arise, you’ll be prompted about the differences between others’ changes and yours. These require manual resolution. After resolving, simply git add and git commit.

Merging Branches:

1
git merge another_branch_name

Here, we’re dealing with the 非fast forward mode, where after branch B is forked from branch A, the parent branch A has changed again. Meanwhile, branch B has also made some modifications. When attempting to merge B back into A, the following scenario occurs:
Note: Assuming you’re on branch A and need to merge branch B, the merg version of branch B must be git push. If branch B has only git commit, it won’t be merged. This is because git merge branch_name’s branch_name is fetched from branch_name’s remote origin to merge. commit only modifies the local HEAD—without push, the remote origin remains unchanged.
Suppose branch B has already git push its changes to the remote, and local branch A has also git add its changes to the local repository. When executing git merge B on branch A (assuming the modified file is config.js), the following occurs:

1
2
3
4
Updating 474cfbf..9c94d0c
error: Your local changes to the following files would be overwritten by merge:config.js
Please commit your changes or stash them before you merge.
Aborting

This means the merge between the two branches failed and was aborted. You’ll be prompted to either stash your current branch’s changes (git stash) or commit them (git commit). After git merge, conflicts will appear for manual resolution before re-submitting.
OK, let’s first git commit the current changes and execute git merge B again. This time, assuming the conflicting file is config.js, the following appears:

1
2
3
Auto-merging config.js
CONFLICT (content): Merge conflict in config.js
Automatic merge failed; fix conflicts and then commit the result.

After manually resolving, re-git add and git commit.

Note: If you modify a file on one branch and checkout to another branch without conflicts, no prompts will appear, and the file changes will persist. Thus, you can modify a file on one branch and later submit it to another. However, if conflicts arise after modifying a file on one branch and checkout another (e.g., the other branch has git pull or git commit the same file in the same way):

1
2
3
4
error: Your local changes to the following files would be overwritten by checkout:
config.js
Please commit your changes or stash them before you switch branches.
Aborting

In this case, you’ll first need to git stash stash (this stash储藏 is not git add暂存. stash temporarily stores files in a specific area. After switching branches, you can apply this stash like a patch to the newly switched checkout branch—or choose not to apply stash. You can wait until tasks on the switched branch are complete, then reapply stash after switching back. Of course, if you never want to apply your stash, that’s fine too).
This brings us to git stash. This command is useful when working on modifications for two branches simultaneously. Suppose you’re halfway through changes on one branch when another branch also requires modifications. You can’t discard half-finished work, nor can you commit, as this might cause conflict when checkout. Thus, you need to stash stash:
First, check the current status with git status:

1
2
3
4
5
6
7
8
9
On branch optimize
Your branch is up-to-date with 'origin/optimize'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)

modified: config.js

no changes added to commit (use "git add" and/or "git commit -a")

Stash the changes with git stash:

1
2
Saved working directory and index state WIP on optimize: 24bf0e1 test add
HEAD is now at 24bf0e1 这是一个提交

Then git status again:

1
2
3
On branch optimize
Your branch is up-to-date with 'origin/optimize'.
nothing to commit, working tree clean

Now, you can safely switch to another branch. Note: When switching, you can also apply the stashed changes to the current branch (if you’re not concerned about conflicts). To view the stash list, use git stash list:

1
stash@{0}: WIP on optimize: 24bf0e1 test add

These are the changes recently stash. You can apply the most recent stash with git stash apply. If there are multiple stash stashes, specify the stash name:

1
git stash apply stash@{0}

Applying will remove this stash from the stash. If you don’t want it deleted, use:

1
git stash apply stash_name --index

To delete it later, run:

1
git stash drop stash_name

Without stash_name, these commands default to deleting the most recent stash.

That’s all I can think of for now. If you’re unfamiliar, it’s safer to use Sourcetree.

Update

git revert/reset/rebase—just reading the instructions won’t make sense. You need to test the commands yourself.

I personally prefer using git rebase for clean commit histories, but this command is dangerous and requires caution in certain scenarios. Even riskier than git rebase is git reset, which resets the entire project to a specific commit. git revert is relatively safer, but if you want to revert a previous commit, it’s best to ensure your staging area is empty to avoid error messages.

Of course, there are countless git commands (slight exaggeration). Some are designed for niche scenarios, and their usage might not make sense until you encounter those situations—this is normal.

For example, git reset commitId moves HEAD to where commitId is located. You might wonder: What’s the point of moving HEAD? What’s the purpose of this command? Similarly, git revert commitId removes commitId’s commits without moving HEAD’s pointer.

Looking at the code (commit d0b9def corresponds to commit -m 'reset/revert test 3', currently HEAD is on 'reset/revert test 4'):

After git revert d0b9def, your code might look like this:

1
2
3
4
5
6
7
reset/revert test 1
reset/revert test 2
<<<<<<< HEAD
reset/revert test 3
reset/revert test 4
=======
>>>>>>> parent of d0b9def... reset/revert test

After performing git reset d0b9def on the same HEAD, your working directory might appear as:

1
2
3
4
 reset/revert test 1
reset/revert test 2
reset/revert test 3
+reset/revert test 4

See the difference between moving and not moving HEAD? revert will always require manual conflict resolution because it preserves all changes from a parent commit prior to your commitId up to the current HEAD, except for d0b9def. On the other hand, reset won’t prompt conflict resolution but silently moves HEAD, displaying all changes since d0b9def as file modifications that require manual git add/commit, not to mention push --force.

Therefore, revert is designed as a safe way to revert commits from 公开, while reset is designed to reset changes from 本地. Since these two commands serve different purposes, their implementations differ: reset completely removes a set of changes, whereas revert preserves the original changes by creating a new commit to undo them.

- EOF -
Originally published at: Summary of Commonly Used Git Commands - Xheldon Blog