my-git

English 中文

Overview

A collection of common, uncommon, and practical Git commands gathered from day-to-day usage, kept here as a personal reference. If you are not familiar with what these commands mean, please refer to: Git for Beginners.

Since Git is used as the version control system in daily development, working with the command line is routine. This document records and organizes the commands used most often, making it easy to look things up later.

[TOC]

Concept

master : default development branch 
origin : default upstream repository 
HEAD : current branch and commit
HEAD^ : parent of HEAD 
HEAD~4 : the great-great grandparent of HEAD

Alias

The examples below are just suggestions — feel free to use whatever abbreviations work for you.

git config --global alias.st status    // abbreviate status as st
git config --global alias.co checkout  // abbreviate checkout as co
git config --global alias.br branch    // abbreviate branch as br
git config --global alias.ci commit    // abbreviate commit as ci
git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"

To remove an alias, simply delete the corresponding line from the config file. For global aliases, run vim ~/.gitconfig and remove the entry under [alias]; for repository-level aliases, edit .git/config instead.

Git Config

Git configuration has three levels: system (--system), user (--global), and repository (--local). The closer the config is to the repository, the higher its priority. When all three define the same setting, the effective order is repository > user > system. Run git config --help for more details.

Basic Usage

Repository

Checkout

The checkout command copies files from the history (or the staging area) to the working directory, and can also be used to switch branches.

Anonymous branch (detached HEAD): If you specify neither a filename nor a branch name, but instead give a tag, remote branch, SHA-1 value, or something like master~3, you end up on an anonymous branch known as a detached HEAD.

When HEAD is in a detached state (not attached to any named branch), commits still work normally, but no named branch is updated. (Think of it as committing to an anonymous branch.) Once you switch to another branch (e.g. master), that commit node may no longer be reachable and will eventually be garbage-collected. Note that after this, nothing refers to 2eecb anymore. For more detail, see: visual-git-guide#detached

If you want to keep the state, use git checkout -b name to create a new branch from it.

Log

Description: Shows the commit logs. The command takes options applicable to the git rev-list command to control what is shown and how, and options applicable to the git diff-* commands to control how the changes each commit introduces are shown. git log [options] [revision range] [path]

Commonly used log commands:

The purpose of log is to trace changes and investigate issues. Besides git log, you can also use git show and git blame to inspect file changes.

Undo things

Reset

The reset command moves the current branch pointer to another position, and optionally modifies the working directory and the index. It can also be used to copy files from a historical commit into the index without touching the working directory.

Reset the working directory to a specific commit: git reset --hard <sha1-of-commit>

Revert

git revert will create a new commit that’s the opposite (or inverse) of the given SHA. If the old commit is “matter”, the new commit is “anti-matter”—anything removed in the old commit will be added in the new commit and anything added in the old commit will be removed in the new commit. This is Git’s safest, most basic “undo” scenario, because it doesn’t alter history—so you can now git push the new “inverse” commit to undo your mistaken commit.

git revert [--[no-]edit] [-n] [-m parent-number] [-s] [-S[<keyid>]] <commit>…​
git revert --continue
git revert --quit
git revert --abort

To undo a single commit from a series without affecting later commits: git revert c2

(https://blog.csdn.net/u013066244/article/details/79920012) https://blog.csdn.net/u013066244/article/details/79920012

Restore

restore takes over the file-restoration responsibility that was previously part of checkout. While checkout could both switch branches and restore working tree files, restore now handles only the restoration side.

git restore restores files in the working tree from either the index or another commit. This command does not update your branch. It can also be used to restore files in the index from another commit.

Revert VS Reset VS Restore

Consider a simple scenario: branch A has five commits — c1, c2, c3, c4, c5. You later discover that commit c2 is problematic and needs to be rolled back. How do you handle it?

Option 1: Using reset Create a new branch A_bak as a copy of the current branch, then run git reset --hard c2 on branch A (this drops c3, c4, c5). Then use git cherry-pick to replay c3, c4, and c5 back onto branch A.

Option 2: Using revert Run git revert c2. This may produce conflicts — resolve them and proceed. If c2 was a merge commit, you need an extra step: git revert c2 -m 1 or git revert c2 -m 2. See: https://blog.csdn.net/u013066244/article/details/79920012

Result: a new commit c6 is created that inverts the changes introduced by c2. If there are conflicts, the conflicting file contents will be shown for manual resolution.

revert is purpose-built for exactly this kind of scenario and should be the go-to command in daily work.

Diff

Merge

Rebase

Rebase and merge produce the same end result — integrating local and remote changes — but they differ in how they do it.

git checkout mywork
git rebase origin

These commands take each commit on the mywork branch, temporarily save them as patches (stored in .git/rebase), update mywork to the latest origin branch, and then reapply the saved patches on top.

A diagram showing the difference between rebase and merge:

During a rebase, conflicts may occur. When they do, Git pauses and lets you resolve them. After resolving, use git add to update the index, then run git rebase --continue (no need to commit) to apply the remaining patches. At any point you can abort the rebase with git rebase --abort, which returns mywork to its state before the rebase started.

Cherry Pick

The cherry-pick command “copies” a commit node and creates an identical new commit on the current branch.

Branch workflow

Aone2 Git branch development and deployment model — detailed breakdown: http://docs.alibaba-inc.com:8090/pages/viewpage.action?pageId=194872297

Branch structure on origin:

To create a branch directly: git checkout -b feature/20161129_163448_newfeature_1

The Git-Develop branching model is a development workflow built around strict control of release quality and cadence. develop serves as the fixed continuous integration and release branch; code can only be merged into it after passing a Code Review. The basic flow is:

Branch Commands

“Checking out a local branch from a remote branch automatically creates what is called a ‘tracking branch’ (or sometimes an ‘upstream branch’). Tracking branches are local branches that have a direct relationship to a remote branch. If you’re on a tracking branch and type git pull, Git automatically knows which server to fetch from and branch to merge into. When you clone a repository, it generally automatically creates a master branch that tracks origin/master. However, you can set up other tracking branches if you wish — ones that track branches on other remotes, or don’t track the master branch. The simple case is the example you just saw, running git checkout -b [branch] [remotename]/[branch]. This is a common enough operation that git provides the –track shorthand.”

Tag

Submodule

Add a submodule: $ git submodule add [url] [path] Example: $ git submodule add git://github.com/soberh/ui-libs.git src/main/webapp/ui-libs Initialize submodules: $ git submodule init — only needs to be run once after the initial clone Update submodules: $ git submodule update — run this after every pull or branch switch Remove a submodule (four steps): 1) $ git rm --cached [path] 2) Edit .gitmodules and remove the submodule’s configuration section 3) Edit .git/config and remove the submodule’s configuration section 4) Manually delete the leftover submodule directory

Stash

It often happens that while you’re working on part of your project and things are in a messy state, you want to switch branches to work on something else. You don’t want to commit half-done work, but you also don’t want to lose it. The solution is git stash.

stash captures the intermediate state of your working directory — your tracked modified files and staged changes — and saves them to a stack of unfinished changes that can be reapplied at any time.

usage: git stash list [<options>]                                         -- list current stashes
   or: git stash show [<stash>]                                           -- show the contents of a stash entry
   or: git stash drop [-q|--quiet] [<stash>]                             -- remove a stash entry
   or: git stash ( pop | apply ) [--index] [-q|--quiet] [<stash>]        -- apply a stash entry to the working directory
   or: git stash branch <branchname> [<stash>]
   or: git stash [save [--patch] [-k|--[no-]keep-index] [-q|--quiet]
		       [-u|--include-untracked] [-a|--all] [<message>]]
   or: git stash clear                                                    -- remove all stash entries

oh-my-zsh Common Aliases

alias g='git'
alias ga='git add'
alias gco='git checkout'
alias gcb='git checkout -b'
alias gcm='git checkout master'
alias gcd='git checkout develop'
alias gd='git diff'
alias gf='git fetch'
alias gfo='git fetch origin'
alias gl='git pull'
alias gp='git push'