Helpful tips and tricks for configuring and using Git are provided below.
Global configuration changes will be applied to the user .gitconfig file (located in the home directory).
Set the globally-scoped name to use for commit signatures.
git config --global user.name <name>Set the user's name.
git config --global user.name "John Doe"Set the globally-scoped user email address to use for commit signatures.
git config --global user.email <email_address>NOTE: As a security measure to protect your email from spam, it is recommended to use an auto-generated no-reply email address, such as those provided through GitHub.
Set the email address.
git config --global user.email john.doe@users.noreply.github.comSet the GPG signing key repositories will use for commit sign-off and user authentication. Additionally, enable GPG signing on repositories by default.
git config --global user.signingkey <signing_key>
git config --global commit.gpgsign true
git config --global tag.forceSignAnnotated true
git config --global tag.gpgsign trueSet the 16-character code for the GPG signing key, and enable GPG signing.
git config --global user.signingkey ****************
git config --global commit.gpgsign true
git config --global tag.forceSignAnnotated true
git config --global tag.gpgsign trueConfigure pull to use the rebase strategy (instead of merge).
git config --global pull.rebase trueNOTE: Using rebase allows your repository to maintain a linear history.
Change the default (master) branch for newly created repositories.
git config --global init.defaultBranch <new_branch_name>Update the default branch name to main (instead of master); this is the new norm--it's also shorter.
git config --global init.defaultBranch mainPush the current branch to its configured upstream branch [only] if the branch names match; fail otherwise.
git config --global push.default simpleAssign a global mailmap file for git to use. This file maps user names and emails to singular identities which can be more easily tracked in log history and commit blames.
git config --global mailmap.file <mailmap_file_path>Assign the git.mailmap file located in the user's ~/.ssh directory.
git config --global mailmap.file ~/.ssh/git.mailmapAssign a global editor for git to use. The editor is used for various interactive git actions, including commit [message] editing and tagging as well as rebasing. If not specified, git instead uses the system editor defined in one of the shell environment variables VISUAL or EDITOR, falling back to the vi editor if neither of those are defined.
git config --global core.editor <editor command>Assign VS Code as the default editor.
git config --global core.editor "code --wait"NOTE: Some alternatives include emacs and nano.
Disable the auto-CRLF feature. This feature can wreak havoc with commits if not supervised. The default setting for Linux-based environments is to disable this feature anyways. Assuming your editor is already configured to use LF-style line-endings, there is no need to enable the feature.
git config --global core.autocrlf falseWARNING: Avoid disabling the auto-CRLF feature if you're developing within a Windows environment, AND your editor is not configured to save with LF-style line endings.
Use distinct coloration to identify lines which have been moved, but have otherwise been left unchanged.
git config --global diff.colorMoved zebraAssign the username to use when working with git-review and Gerrit.
git config --global --add gitreview.username <username>NOTE: The <username> parameter is the username associated with Gerrit.
NOTE: This configuration is only helpful when working with git-review and is otherwise unnecessary.
Assign the Gerrit username jdoe.
git config --global --add gitreview.username jdoeThe following commands have more common usecases used outside of initial setup.
Create a new branch from the current branch at the specified commit.
git checkout -b new_branch_name <commit_hash>NOTE: The <commit_hash> parameter refers to the hash of a commit from the current branch that the new branch will start at.
Update the current local branch with the most recent changes from the branch stored on the remote repository.
git pull --rebase origin <remote_branch_name>NOTE: The remote_branch_name parameter is the branch that the current branch will be rebased against.
Update the current branch with the most recent changes from the remote copy of the main branch.
git pull --rebase origin mainUpdate the current local branch with the most recent changes from the specified local branch.
git rebase <local_source_branch_name>NOTE: The <local_source_branch_name> parameter is the name of the local branch that the current branch will be rebased against.
Update the current branch with changes from the local copy of the dev branch.
git rebase devUpdate the current local branch with the most recent changes from the specified local branch using the merge strategy.
git merge <local_source_branch_name>NOTE: The <local_source_branch_name> parameter is the name of the local branch that the current branch will be rebased against.
Update the current branch with changes from the local copy of the dev branch.
git merge devUpdate the current local branch with the specified range of commits (commit A included). The current branch is updated by rebasing the specified range of commits on top of it.
git cherry-pick A^..BNOTE: The letters A and B above represent the hashes of the commits in the desired range. They may be abbreviated hashes.
Alternatively, the following command[s] will cause the metadata for the new commits to retain the original authors and author[ed] dates:
# NOTE: This will leave the repository at a detached head
git rebase --onto <branch_name> A^ B
# NOTE: These commands will update the specified branch to the new head
git branch -f <branch_name> HEAD
git checkout <branch_name>NOTE: The <branch_name> parameter is the name of the branch whose HEAD will be changed.
List the files with outstanding conflicts caused by an in-progress merge/rebase.
git diff --name-only --diff-filter=UUpdate the target remote branch with changes from the specified local branch.
git push origin <local_source_branch_name>:<remote_target_branch_name>NOTE: The <local_source_branch_name> parameter is the name of the local source branch from which the <remote_target_branch_name> remote branch will be updated.
Update the origin's main branch with changes from the local dev branch.
git push origin dev:mainSet the upstream remote branch for the current branch to the specified target branch. Subsequent pushes and pulls from the current local branch will interact with the specified remote target branch.
git push -u origin <remote_target_branch_name>NOTE: The <remote_target_branch_name> parameter is the name of the remote target branch to which changes from the current local branch will be pushed. Subsequent pushes and pulls from the current local branch will interact with the specified remote branch.
Set the remote upstream branch for the current local branch to main, and push changes to it.
git push -u origin mainRename the specified local branch with the specified replacement name.
git branch -m <local_branch_name> <new_branch_name>NOTE: The <local_branch_name> parameter is the name of the local branch being renamed, and the <new_branch_name> parameter is the new name the branch is receiving.
Rename the dev branch to test.
git branch -m dev testDelete the specified remote branch.
git push origin --delete <remote_branch_name>Alternatively, use:
git push origin :<remote_branch_name>NOTE: The <remote_branch_name> parameter is the name of the remote branch to be deleted.
Delete the remote dev and test branches.
git push origin --delete dev
git push origin :testDelete the specified local branch.
git branch -d <local_branch_name>NOTE: The <local_branch_name> parameter is the name of the local branch to be deleted.
NOTE: The -D argument may be required (instead of -d) to force branch deletion if the local branch contains changes not captured in the corresponding upstream branch on the remote repository.
Delete the local dev branch.
git branch -d devLog the new commits on the specified branch from where it diverges from the current local branch.
git log --first-parent <branch_name>NOTE: The <branch_name> parameter is the name of the branch whose commits should be logged.
Log the new commits on the local dev branch.
git log --first-parent devLog the most recent N commits, reserving one line for each commit.
git log --oneline [-<N>]Log the most recent 5 commits in one line each.
git log --oneline -5Print the author information of the most recent N commits on the specified branch.
git log --pretty=format:"[%h] %ad - %an <%ae>" [<branch_name>] [-<N>]NOTE: The %h argument instructs pretty to print the abbreviated commit hash.
NOTE: The %ad argument instructs pretty to print the author[ed] date.
NOTE: The %an argument instructs pretty to print the author name.
NOTE: The %ae argument instructs pretty to print the author email.
NOTE: The <branch_name> parameter is the name of the branch whose commits should be logged.
NOTE: Printing the author date is often helpful when patching the author name/email of commits for consistency, since resetting the author will also modify the author date unless overridden.
NOTE: The git mailmap file will come in handy here.
Alternatively, use the git show command to print the author information for a specific commit.
git show --pretty=format:"[%h] %ad - %an <%ae>" <commit_hash>NOTE: The <commit_hash> parameter refers to the hash of a commit for which the author information will be printed.
Print the author information of the most recent 3 commits on the local dev branch.
git log --pretty=format:"[%h] %ad - %an <%ae>" dev -3Print the number of commits made by each author--on (all) branches.
git shortlog -sn --allNOTE: The -n argument performs a descending sort on the results.
NOTE: The -s argument suppresses commit description, showing only the count.
Print the number of commits made by the specified author in the current local branch.
git shortlog -sn --author="<author_name>"NOTE: The <author_name> parameter is the name of the author whose commits should be counted.
NOTE: The git mailmap file will come in handy here.
Print the number of commits made by John Doe.
git shortlog -sn --author="John Doe"Set the author name and email for commits in the current branch to the current user name and email as specified by .gitconfig and accessible as git config user.name and git config user.email.
git rebase -r <commit_hash> --exec 'git commit --amend --no-edit --reset-author --signoff'NOTE: The <commit_hash> parameter specifies the hash of the most recent commit that won't be included in the modifications; all newer commits will be included.
WARNING: This command will also reset the author date for the updated commits to the current date. To preserve the original author date, the commits must be individually amended via an interactive rebase with the date parameter specified.
NOTE: Printing the author date is often helpful when patching the author name/email of commits for consistency, since resetting the author will also modify the author date unless overridden.
NOTE: The git mailmap file will come in handy here.
Alternatively, preserve the author dates by first printing the author date information (e.g. via git log --pretty=format:"[%h] %ad") and by subsequently performing an interactive rebase, amending each commit with the proper date.
git rebase -i -r <commit_hash>
# Repeat the following steps as necessary
git commit --amend --no-edit --reset-author --date="<author_date>" --signoff
git rebase --continueReset the author information for the most recent 3 commits.
git rebase -r HEAD~3 --exec 'git commit --amend --no-edit --reset-author --signoff'Print the committer information of the most recent N commits on the specified branch.
git log --pretty=format:"[%h] %cd - %cn <%ce>" [<branch_name>] [-<N>]NOTE: The %h argument instructs pretty to print the abbreviated commit hash.
NOTE: The %cd argument instructs pretty to print the commit[ted] date.
NOTE: The %cn argument instructs pretty to print the committer name.
NOTE: The %ce argument instructs pretty to print the committer email.
NOTE: The <branch_name> parameter is the name of the branch whose commits should be logged.
NOTE: The git mailmap file will come in handy here.
Alternatively, use the git show command to print the committer information for a specific commit.
git show --pretty=format:"[%h] %cd - %cn <%ce>" <commit_hash>NOTE: The <commit_hash> parameter refers to the hash of a commit for which the committer information will be printed.
Print the committer information of the most recent 3 commits on the local dev branch.
git log --pretty=format:"[%h] %cd - %cn <%ce>" dev -3Print the signer information of the most recent N commits on the specified branch.
git log --pretty=format:"[%h] %G? %GG - Signer: %GS, %GK, %GF, %GT" [<branch_name>] [-<N>]NOTE: The %h argument instructs pretty to print the abbreviated commit hash.
NOTE: The %G? argument instructs pretty to print the status of a signature (G, B, U, X, Y, R, E, N).
NOTE: The %GG argument instructs pretty to print the raw verification message for a signed commit.
NOTE: The %GS argument instructs pretty to print the signer (name and email) for a signed commit.
NOTE: The %GK argument instructs pretty to print the key used to sign a commit.
NOTE: The %GF argument instructs pretty to print the fingerprint of the primary key whose subkey was used to sign a commit.
NOTE: The %GT argument instructs pretty to print the trust level for the key used to sign a commit.
NOTE: The <branch_name> parameter is the name of the branch whose commits should be logged.
NOTE: The git mailmap file will come in handy here.
Alternatively, use the git show command to print the signer information for a specific commit.
git show --pretty=format:"[%h] %G? %GG - Signer: %GS, %GK, %GF, %GT" <commit_hash>NOTE: The <commit_hash> parameter refers to the hash of a commit for which the signer information will be printed.
Print the signer information of the most recent 3 commits on the local dev branch.
git log --pretty=format:"[%h] %G? %GG - Signer: %GS, %GK, %GF, %GT" dev -3List the remote repositories.
git remote -vAdd a remote repository to the list of remotes with the specified remote name.
git remote add <new_remote_name> <new_remote_url>NOTE: The <new_remote_name> parameter is the name that will be assigned to the remote within the context of the local git repository.
NOTE: The <new_remote_url> parameter is the URL of the new remote repository being added.
Add the passed repository URL to the local repository as the origin remote.
git remote add origin git@github.com:jekyll/jekyll.gitChange the URL associated with a locally-configured remote repository name.
git remote set-url <remote_name> <new_remote_url>NOTE: The <remote_name> parameter is the locally-associated name of the remote repository whose URL will be re-assigned.
NOTE: The <new_remote_url> parameter is the new URL the remote name is to be associated with.
NOTE: This tends to be useful with working with forks or multiple repositories with the same base code.
Change the URL associated with the origin remote.
git remote set-url origin git@github.com:jekyll/jekyll.gitChange the name of a locally-configured remote repository.
git remote rename <remote_name> <new_remote_name>NOTE: The <remote_name> parameter is the locally-associated name of the remote repository.
NOTE: The <new_remote_name> parameter is the new locally-associated name for the remote repository.
NOTE: This tends to be useful with working with forks or multiple repositories with the same base code.
Change the name of the origin remote to jekyll.
git remote rename origin jekyllList the files modified within the specified range of commits.
git show --pretty="format:" --name-only <BEGIN_COMMIT>..<END_COMMIT> | sort | uniqNOTE: The <BEGIN_COMMIT> parameter is the hash of the first commit in the range.
NOTE: The <END_COMMIT> parameter is the hash of the last commit in the range.
NOTE: The commit hashes may be abbreviated.
Amend the commit messages of the most recent <N> commits.
git rebase -i -p HEAD~<N>Amend the commit messages of the most recent 3 commits.
git rebase -i -p HEAD~3Undo the most recent <N> commits in the commit history for the current local branch, but retain the associated changes locally for subsequent revision.
git reset HEAD~<N> --softNOTE: The <N> parameter specifies the number of commits to revert.
NOTE: This can be helpful when you'd like to update a preceding commit with some of those changes, such as with commit --amend.
Undo the most recent local commit, while retaining the changes in the local repository.
git reset HEAD~1 --softInteractively rearrange, edit, drop, etc. commits from the current [local] branch.
git rebase -i -r <commit_hash>NOTE: The <commit_hash> parameter specifies the hash of the most recent commit that won't be included in the modifications; all newer commits will be included.
Interactively modify the most recent three local commits.
git rebase -i -r HEAD~3Clean the repository of orphaned commits.
git reflog expire --expire-unreachable=now --all
git gc --prune=nowNOTE: During branch modifications, deletions, resets, etc. previously reachable commits can become "orphaned"--that is they can become no longer reachable within the existing branches. Data for those commits is retained, such that it may subsequently be recovered. However, if those changes are no-longer needed, as is likely, than the repository can be cleaned up to recover some space and reduce its digital footprint.
Search commit changes for specified text.
git log -S "<text>" --source --allNOTE: The <text> parameter is the text to be searched for.
Search commit changes for "Hello world".
git log -S "Hello world" --source --allList the files changed in a specified commit along with their status.
git show --name-status <commit_hash>NOTE: The <commit_hash> parameter is the hash of the commit whose files should be listed.
NOTE: The commit hash can be abbreviated.
Only list the files that were added in a specified commit.
git show --name-status <commit_hash> | grep "^A"Alternatively, the following should work, but doesn't seem to...
git show --name-status --porcelain <commit> | grep "^A" | cut -c 4-NOTE: The <commit_hash> parameter is the hash of the commit whose files should be listed.
NOTE: The commit hash can be abbreviated.
List the number of files changed in a specified commit.
git log --oneline --name-status <commit_hash> -1 | wc -lNOTE: The <commit_hash> parameter is the hash of the commit whose files should be listed.
NOTE: The commit hash can be abbreviated.
Change the head of a branch to the specified commit.
git checkout <another_branch_name>
git branch -f <branch_name> <commit_hash>NOTE: First must change to another local branch to proceed with the operation safely.
NOTE: The <another_branch_name> parameter is the name of another branch.
NOTE: The <branch_name> parameter is the name of the branch whose HEAD will be changed.
NOTE: The <commit_hash> parameter is the hash of the commit to which the HEAD of the <branch_name> branch will point.
NOTE: The commit hash can be abbreviated.
Alternatively, the following command[s] can be used to change the head of the current branch:
git checkout <branch_name>
git reset --hard <commit_hash>WARNING: The alternate method exposes your local repository to the potential loss of any unsaved/uncommitted changes.
Change the head of the main branch to the specified commit.
git checkout dev
git branch -f main ABCDEFInitialize and update all submodules, recursively.
git submodule update --init --recursiveAdd the specified repository as a submodule to the current repository.
git submodule add <remote_repository_url>NOTE: The <remote_repository_url> parameter is the URL of the remote repository to be added as a submodule.
Add Jekyll as a submodule to the current repository.
git submodule add git@github.com:jekyll/jekyll.gitRemove the specified submodule from the current repository.
# Manually delete the relevant section from the .gitmodules file.
# Stage the .gitmodules changes
git add .gitmodules
# Delete the relevant section from .git/config.
# Run the following command (with no trailing slash):
git rm --cached path_to_submodule
# Run the following command (with no trailing slash):
rm -rf .git/modules/path_to_submodule
# Commit changes
git commit -m "Removed submodule "
# Delete the now untracked submodule files
rm -rf path_to_submodule