Command
-
push
-f
/--force
- Ensure remote repo is the same as the local repo
- How to use git push force the right way (opens in a new tab)
Notes
-
Pull
-
merging
git pull --merge
If you pull remote changes with the flag --merge, which is also the default, then your local changes are merged with the remote changes. This results in a merge commit that points to the latest local commit and the latest remote commit.
-
-
Merge
-
Make sure there was no uncommitted changes before the merge started
-
A
fast-forward
merge can only be done when the most recent commit on the target branch is an ancestor in the source branch (i.e. the commit at the tip of the receiving branch (main) must appear somewhere in the branch providing the new commits (feat/x) ).
-
-
Log
git log
-
--oneline
Display
log
in compactone-line
format -
--branches
Specifiy the
branch
,current branch
if omitted
-
Revisions
-
<rev>
Include commits that are reachable from
<rev>
(i.e.<rev>
and its ancestors). -
^<rev>
Exclude commits that are reachable from
<rev>
(i.e.<rev>
and its ancestors). -
<rev1>..<rev2>
Include commits that are reachable from
<rev2>
but exclude those that are reachable from<rev1>
. When either<rev1>
or<rev2>
is omitted, it defaults toHEAD
. -
<rev1>...<rev2>
Include commits that are reachable from either
<rev1>
or<rev2>
but exclude those that are reachable from both. When either<rev1>
or<rev2>
is omitted, it defaults toHEAD
. -
<rev>^@
, e.g.HEAD^@
A suffix
^
followed by@
is the same as listing all parents of<rev>
(meaning, include anything reachable from its parents, but not the commit itself). -
<rev>^!
, e.g.HEAD^!
A suffix
^
followed by!
is the same as giving commit<rev>
and all its parents prefixed with^
to exclude them (and their ancestors). -
<rev>^-<n>
, e.g.HEAD^-
,HEAD^-2
Equivalent to
<rev>^<n>..<rev>
, with<n> = 1
if not given.
G H I J
\ / \ /
D E F
\ | / \
\ | / |
\|/ |
B C
\ /
\ /
A
A = = A^0
B = A^ = A^1 = A~1
C = = A^2
D = A^^ = A^1^1 = A~2
E = B^2 = A^^2
F = B^3 = A^^3
G = A^^^ = A^1^1^1 = A~3
H = D^2 = B^^2 = A^^^2 = A~2^2
I = F^ = B^3^ = A^^3^
J = F^2 = B^3^2 = A^^3^2
Args | Expanded arguments | Selected commits |
---|---|---|
D | G H D | |
D F | G H I J D F | |
^G D | H D | |
^D B | E I J F B | |
^D B C | E I J F B C | |
C | I J F C | |
B..C | ^B C | C |
B...C | B ^F C | G H D E B C |
B^- | B^..B | |
^B^1 B | E I J F B | |
C^@ | C^1 | |
F | I J F | |
B^@ | B^1 B^2 B^3 | |
D E F | D G H E F I J | |
C^! | C ^C^@ | |
C ^C^1 | ||
C ^F | C | |
B^! | B ^B^@ | |
B ^B^1 ^B^2 ^B^3 | ||
B ^D ^E ^F | B | |
F^! D | F ^I ^J D | G H D F |
Dotted Range Notations
-
<rev1>..<rev2>
Examples
-
g log origin..HEAD
What did I do since I forked from the
origin
branch? -
g log HEAD..origin
What did the
origin
do since I forked from them?
-
Cheatsheet
Run Git command from another directory
git -C $directory $command
Check out a specific commit
to the working copy in detached HEAD
state
-
Notes
- To keep the changes in
detached HEAD
state: switching to a new branch - To discard the changes in
detached HEAD
state: switching to an existing branch
- To keep the changes in
-
git checkout <COMMIT_ID>
or
-
git switch -d <COMMIT_ID>
(>= 2.23)
Return to HEAD
of previous branch
git switch -` (**>= 2.23**) or a specific branch `git switch <branch_name>
Update and replace the most recent commit
-
git commit --amend (--no-edit / -m <message>)
-
--amend
The latest
commit
will be replaced by thenew commit
. -
--no-edit
Keep the same
commit message
, or provide a newcommit message
with-m
-
Commit changes of a specific file or directory
git commit -m <commit_message> -- <file/dir>
Log
Show log of a single file
git log --follow -- <file>
Shows the log of the specified file in spite of renaming
Show log of a single file with diff
git log --follow -p -- <file>
Shows the log of the specified file in spite of renaming, with diff
Show log of most recent commits
g log -$number
e.g. g log -10
Show log of changed file names
g log --name-status
Show summary of log
g shortlog
Show log of commits in hash
g log --format=%H
Show logs with full hashes
g log --no-abbrev
Search log by commit message matching the specified regex
g log --grep="$regex"
Search log by patch text matching the specified regex
-
g log -E -G<regex> --name-status --oneline --source --all
Use this to list files with contents matching the given regex
-
g log -E -G<regex> --name-status --oneline --source --all | egrep 'refs/.+?\s|$'
Search log by date
-
g log --since 2022-01-01
-
g log --until 2022-01-01
Search log by author
g log --author $author
Use a regex to match author name(s)
Diff the log between local branch and another branch
Recommended before git pull
-
Show diff of each commit
git log HEAD..origin/master
-
Show commits only
git log --oneline --graph HEAD..origin/master
-
Show a single combined diff of all commits
git diff HEAD..origin/master
-
Resources
List all revisions of a file
g rev-list --all -- $file
Show all diff of a file
g log -p -- $file
List all files changed in a commit
g show --oneline --name-status $commit_id
View a file of a specific commit
g show $commit_id:$file
Search file contents by regex pattern in all tracked files
g grep --heading --break -C2 -E "$regex" $(g log -G'direnv' --format=%H)
Use Git
log to narrow down commits range
Change remote repo URL
git remote -v
git remote set-url origin <url>
Stash
-
Work as a stack,
FILO
-
Default stash name
when no
<stash>
is given,stash@{0}
is assumed, otherwise<stash>
must be a reference of the formstash@{<revision>}
.
Save working copy changes to a new stash with the default name
g stash (push)
Show existing stashed changes
g stash list
Show the changes recorded in the stash entry as a diffstat
-
as
diffstat
g stash show
-
as
diff
g stash show -p
Remove everything in the stash
g stash clear
Apply the most recent pushed stashed changes to working copy
g stash (pop | apply)
Interactively select each hunk (consecutive lines of change in a file) you want to stash
g stash push --patch
Patch
Create a patch file for staged changes
g diff --staged > $patch_file
Create a patch file for a single commit relative to the current branch
g format-patch -1 $commit_id
Create one patch file for each commit relative to a specific branch
g format-patch $branch_name
Create one patch file for all commits consolidated relative to a specific branch
g format-patch $branch_name --stdout > $patch_file
Apply a patch file without committing
g apply $patch_file
Apply a patch file and commit
g am $patch_file
Abort on supplying commit message in Vim
Use :cq
to make Vim
quit with an error code
, and Git
will abort the operation.
Revert committed changes
g revert $commit_id
Git
will apply changes opposite to the specified commit
to reverse the effects by creating a new commit
.
More useful on a public branch
, as it doesn't alter the existing commit history.
Delete unversioned directories and files
To remove directories
g clean -fd
To remove ignored files
g clean -fX
To remove ignored and non-ignored files
g clean -fx
To remove ignored and non-ignored files interactively
g clean -id
Dry run cleaning unversioned files
g clean -n
Remove a file from repository but keeping local copy
g rm --cached $file
Merge
Check if a fast-foward merge is possible
g merge-base --is-ancestor $(gb --show-current) $branch_to_merge_from
Merge a topic branch with squashed commits
g merge --squash $branch_name
- All changes will be staged in working copy under the current
branch
, therefore still need to be committed. - Use
git commit
will put all commit messages in the draft for editing.
Dry-run a merge
-
git merge --no-commit --no-ff <branch>
or
gm --no-commit --no-ff <branch>
Changes stay in index
-
git merge --abort
Reset the index
Choose a merge strategy when merging
-
g merge -s <strategy> -X <option> --no-commit <branch-name>
Choose changes from target branch over local branch
-
g merge -s ours --no-commit <branch-name>
Favor ours
-
g merge -X theirs --no-commit <branch-name>
Favor theirs
Abort a merge process
git reset --merge
git merge --abort
Merge an upstream repository into your fork
-
Retrieve a local copy of upstream branch to be merged
g remote add upstream <upstream_git_url> g fetch upstream <branch_source>
-
Switch to the branch you want to merge the changes into
g switch <branch_target>
-
Merge the changes from upstream repo
g merge upstream/<branch_source>
or
g merge '@{u}'
Rebase
Rebase a branch interactively
g rebase -i $branch
Rebase while pulling changes
g pull --rebase
If you pull remote changes with the flag --rebase
, then your local changes are reapplied on top of the remote changes.
Link an existing local Git repo to a remote repo
g remote add origin $repo_url
g push -f origin $branch
Convert a short hash to a full hash
g rev-parse $short_hash
Show the name of current branch
g rev-parse --abbrev-ref HEAD
or 2.22+
g branch --show-current
Show the absolute path of the top-level directory of the working tree
g rev-parse --show-toplevel
Create a tag with message
g tag -a $tag -m $message
If message omitted, editor will be opened to input message.
Create a local branch with the specified remote tracking branch
g checkout -b $new_branch $remote_branch
or
g checkout -b $new_branch $remote_branch
Show remote tracking branches for all local branches
g branch -vv
Clone a branch or tag
git clone --depth 1 --branch $tag_name $repo_url
using --depth 1
to only download one commit
Push local tag(s) to remote
git push $remote $tag
Push the specified local tag
or
git push --tags
Push all local tags
Fetch a single tag from remote
g fetch $remote tag $tag_name --no-tags
Fetch all tags from remote
g fetch [$remote] --tags
Delete a remote tag
g push --delete $remote $tag_name
Delete all remote tags
g push --delete $remote $(git tag -l)
List all local tags
g tag -l
List local tags with pattern
g tag -l "$regex"
e.g. g tag -l "v*"
Checkout a local tag
g checkout $tag_name
Checkout a local tag into a branch
g checkout tags/$tag_name -b $branch_name
Delete a local tag
g tag -d $tag_name
Delete all local tags
g tag -d $(git tag -l)
Delete a local branch
g branch -d $localBranchName
Delete a remote branch
g push origin --delete $remoteBranchName
Unstage a file and keep local changes
git restore --staged <FILE>
git reset <FILE>
Unstage a file and discard local changes
g restore $file
Delete all commits since the specified commit
git reset --hard $commit_id
- Discard all changes (both uncommited and committed) since the specified
COMMIT ID
- can be used to reset
unfinished merge
Delete the last commit from history
git reset --hard HEAD~1
Restore a historic version of a file
git restore --source $commit_id $file
Recover a lost commit
-
git reflog
This command displays all
HEAD
changes, so you can get any lostCOMMIT_ID
.And use the
COMMIT_ID
to recover any changes bygit restore -s <COMMIT_ID> <DIR/FILE>
Config
List Git
config (globally or locally)
git config -l [--global|--local]
Display Git config variables
man git config
Display remote repo URL
git config remote.origin.url
Turn off oh-my-zsh
repo status
git config --add oh-my-zsh.hide-status 1
git config --add oh-my-zsh.hide-dirty 1
Check if a file is being ignored
-
git check-ignore -v <file1 [file2]...>
If ignored, output would show the matched pattern with line number in Git ignore file.
If not ignored, no output would display.
Ignore a directory
-
Add the directory name to
.gitignore
followed by a slashdirectory-to-ignore/
List versioned files
git ls-files -v <file1 [file2]...>
List modified files
git ls-files -m <file1 [file2]...>
Rename a local branch
# Switch to the branch to be renamed
git switch $branch_to_be_renamed
# Rename the branch
git branch -m $new_branch_name
Cherry-pick commits from another branch
-
Use case
-
Production bug fix
- Use
main
branch to check in bug fix - Then use
cherry-pick
to merge commits back tofeature
branch (pull
is ideally better, but in practicemain
branch often has other commits that you don't want.)
- Use
-
-
Resources
Update from remote upstream branch
git stash
git pull --rebase
git stash pop
Submodule
Submodule - Add a submodule
-
g submodule add -b <branch> <repo-URL> <folder-name>
-
Submodule added before
fatal: A git directory for 'playground-messaging-http-simulator' is found locally with remote(s): origin git@gitlab.com:playground-messaging/playground-messaging-http-simulator.git If you want to reuse this local git directory instead of cloning again from git@gitlab.com:playground-messaging/playground-messaging-http-simulator.git use the '--force' option. If the local git directory is not the correct repo or you are unsure what this means choose another name with the '--name' option.
In this case, use
--force
option, you will see something similar to:Reactivating local git directory for submodule 'playground-messaging-http-simulator'
Submodule - Remove a submodule
-
Steps
- Remove submodule directory under parent repo directory:
rm -rf <submodule-dir>
- Remove submodule directory from index:
g rm --cached <submodule-dir>
- Remove submodule directory under
.git
directory:rm -rf .git/modules/<submodule-name>
- Remove submodule entry with name
<submodule-name>
from file.git/config
- Remove submodule entry with name
<submodule-name>
from file.gitmodules
under parent repo directory.
- Remove submodule directory under parent repo directory:
-
Stack Overflow - Git submodule add: "a git directory is found locally" issue (opens in a new tab)
Submodule - Commit changes when a submodule is changed
- When a submodule has new commits, the parent repo needs to be updated with the latest commit.
LFS
LFS - Initialize Git LFS
- This will update Git hooks to track large files
- Handling Large Files with LFS | Learn Git Ebook (CLI Edition) (opens in a new tab)
git lfs install
LFS - Track files of a pattern with Git LFS
- Always execute the "track" command from the root of your project. The reason for this advice is that patterns are relative to the folder in which you ran the command.
- The
$file_pattern
is case sensitive. - The
$file_pattern
will be added to.gitattributes
file. - Use
git lfs status
andgit lfs ls-files
to verify if the pattern is working as expected.
git lfs track $file_pattern
LFS - List all files tracked by Git LFS
git lfs ls-files -adls
# Output
filepath: media/image/photo/select1.JPG
size: 5456070
checkout: true
download: true
oid: sha256 817b09f77dc45ba9351daab70e5735a41af7d3b60524690ab314e0c1ac069cf3
version: https://git-lfs.github.com/spec/v1
LFS - Get Git LFS environment
git lfs env
# Output
git-lfs/3.2.0 (GitHub; linux amd64; go 1.19.4)
git version 2.43.0
Endpoint=https://gitlab.com/some-repo.git/info/lfs (auth=none)
SSH=git@gitlab.com:some-repo.git
LocalWorkingDir=/local-repo-dir
LocalGitDir=/local-repo-dir/.git
LocalGitStorageDir=/local-repo-dir/.git
LocalMediaDir=/local-repo-dir/.git/lfs/objects
LocalReferenceDirs=
TempDir=/local-repo-dir/.git/lfs/tmp
ConcurrentTransfers=8
TusTransfers=false
BasicTransfersOnly=false
SkipDownloadErrors=false
FetchRecentAlways=false
FetchRecentRefsDays=7
FetchRecentCommitsDays=0
FetchRecentRefsIncludeRemotes=true
PruneOffsetDays=3
PruneVerifyRemoteAlways=false
PruneRemoteName=origin
LfsStorageDir=/local-repo-dir/.git/lfs
AccessDownload=none
AccessUpload=none
DownloadTransfers=basic,lfs-standalone-file,ssh
UploadTransfers=basic,lfs-standalone-file,ssh
GIT_EXEC_PATH=/git-installation/libexec/git-core
git config filter.lfs.process = "git-lfs filter-process"
git config filter.lfs.smudge = "git-lfs smudge -- %f"
git config filter.lfs.clean = "git-lfs clean -- %f"
LFS - Get Git LFS status
g lfs status
# Output
On branch develop
Objects to be pushed to origin/develop:
Objects to be committed:
.gitattributes (Git: ed72c32 -> Git: fbc4da5)
media/image/photo/_DSC9253.JPG (LFS: b737ca9)
Objects not staged for commit:
GitHub CLI
List all Gists
gh gist list -L 50
Edit a Gist locally
gh gist edit $ID
Add a local file to a Gist
gh gist edit $ID -a $file
Create a Gist based on a local file
gh gist create -f $file_name_on_Gist -d $description < $local_file
git-extras
Gitflow
-
develop
branch to include allfeature
developmentmain
->develop
-
Release preparation
develop
->release
-
New feature
develop
->feature
-
Bug fix
main
->hotfix
-
When a
feature
is complete, it is merged intodevelop
-
When the
release
branch is done, it is merged intodevelop
andmain
-
Once the
hotfix
is completehotfix
=>develop
hotfix
=>main
Commit message management
Message format
[$Tag] $Subject
Message tags
Tag | Description |
---|---|
feat | A new feature |
fix | A bug fix |
docs | Documentation only changes |
style | Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc) |
refactor | A code change that neither fixes a bug nor adds a feature |
perf | A code change that improves performance |
test | Adding missing tests or correcting existing tests |
plumbing | Changes to the build process or auxiliary tools and libraries such as documentation generation |
Resources
-
Commit Often, Perfect Later, Publish Once: Git Best Practices (opens in a new tab)
-
Atlassian Git Tutorial - Gitflow Workflow (opens in a new tab)
-
Git Config