Skip to content

Latest commit

 

History

History
839 lines (538 loc) · 23.9 KB

File metadata and controls

839 lines (538 loc) · 23.9 KB

Git

Helpful tips and tricks for configuring and using Git are provided below.

Global Configuration

Global configuration changes will be applied to the user .gitconfig file (located in the home directory).

Assign User's Name

Set the globally-scoped name to use for commit signatures.

git config --global user.name <name>

Example

Set the user's name.

git config --global user.name "John Doe"

Assign Signing Email

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.

Example

Set the email address.

git config --global user.email john.doe@users.noreply.github.com

Assign GPG Signing Key

Set 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 true

Example

Set 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 true

Rebase On Pull

Configure pull to use the rebase strategy (instead of merge).

git config --global pull.rebase true

NOTE: Using rebase allows your repository to maintain a linear history.

Update Default Branch Name

Change the default (master) branch for newly created repositories.

git config --global init.defaultBranch <new_branch_name>

Example

Update the default branch name to main (instead of master); this is the new norm--it's also shorter.

git config --global init.defaultBranch main

Only Push Matching Branch

Push the current branch to its configured upstream branch [only] if the branch names match; fail otherwise.

git config --global push.default simple

Assign Mailmap File

Assign 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>

Example

Assign the git.mailmap file located in the user's ~/.ssh directory.

git config --global mailmap.file ~/.ssh/git.mailmap

Assign Editor

Assign 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>

Example

Assign VS Code as the default editor.

git config --global core.editor "code --wait"

NOTE: Some alternatives include emacs and nano.

Disable Auto-CRLF

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 false

WARNING: 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.

Enable Diff Color Distinction for Moved Lines

Use distinct coloration to identify lines which have been moved, but have otherwise been left unchanged.

git config --global diff.colorMoved zebra

Assign Git-Review Username

Assign 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.

Example

Assign the Gerrit username jdoe.

git config --global --add gitreview.username jdoe

Routine Usage

The following commands have more common usecases used outside of initial setup.

Create Branch

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 Branch from Remote

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.

Example

Update the current branch with the most recent changes from the remote copy of the main branch.

git pull --rebase origin main

Update Branch from Local - Rebase Strategy

Update 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.

Example

Update the current branch with changes from the local copy of the dev branch.

git rebase dev

Update Branch from Local - Merge Strategy

Update 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.

Example

Update the current branch with changes from the local copy of the dev branch.

git merge dev

Update Branch from Range of Commits

Update 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^..B

NOTE: 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 Files with Conflicts

List the files with outstanding conflicts caused by an in-progress merge/rebase.

git diff --name-only --diff-filter=U

Update Remote Branch from Local

Update 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.

Example

Update the origin's main branch with changes from the local dev branch.

git push origin dev:main

Pair Local Branch with Remote Branch

Set 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.

Example

Set the remote upstream branch for the current local branch to main, and push changes to it.

git push -u origin main

Rename Local Branch

Rename 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.

Example

Rename the dev branch to test.

git branch -m dev test

Delete Remote Branch

Delete 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.

Example

Delete the remote dev and test branches.

git push origin --delete dev
git push origin :test

Delete Local Branch

Delete 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.

Example

Delete the local dev branch.

git branch -d dev

Log New Commits

Log 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.

Example

Log the new commits on the local dev branch.

git log --first-parent dev

Log Commits in One Line

Log the most recent N commits, reserving one line for each commit.

git log --oneline [-<N>]

Example

Log the most recent 5 commits in one line each.

git log --oneline -5

Print Author of Commits

Print 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.

Example

Print the author information of the most recent 3 commits on the local dev branch.

git log --pretty=format:"[%h] %ad - %an <%ae>" dev -3

Print Number of Commits Per Author

Print the number of commits made by each author--on (all) branches.

git shortlog -sn --all

NOTE: The -n argument performs a descending sort on the results.
NOTE: The -s argument suppresses commit description, showing only the count.

Print Number of Commits by Author

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.

Example

Print the number of commits made by John Doe.

git shortlog -sn --author="John Doe"

Update Author Name and/or Email

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 --continue

Example

Reset the author information for the most recent 3 commits.

git rebase -r HEAD~3 --exec 'git commit --amend --no-edit --reset-author --signoff'

Print Committer of Commits

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.

Example

Print the committer information of the most recent 3 commits on the local dev branch.

git log --pretty=format:"[%h] %cd - %cn <%ce>" dev -3

Print Signer of Commits

Print 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.

Example

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 -3

List Remote Repositories

List the remote repositories.

git remote -v

Add Remote Repository

Add 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.

Example

Add the passed repository URL to the local repository as the origin remote.

git remote add origin git@github.com:jekyll/jekyll.git

Assign New Remote URL

Change 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.

Example

Change the URL associated with the origin remote.

git remote set-url origin git@github.com:jekyll/jekyll.git

Rename Remote

Change 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.

Example

Change the name of the origin remote to jekyll.

git remote rename origin jekyll

List Changed Files

List the files modified within the specified range of commits.

git show --pretty="format:" --name-only <BEGIN_COMMIT>..<END_COMMIT> | sort | uniq

NOTE: 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.

Modify Commit Messages

Amend the commit messages of the most recent <N> commits.

git rebase -i -p HEAD~<N>

Example

Amend the commit messages of the most recent 3 commits.

git rebase -i -p HEAD~3

Undo Commits

Undo 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> --soft

NOTE: 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.

Example

Undo the most recent local commit, while retaining the changes in the local repository.

git reset HEAD~1 --soft

Rearrange, Edit, and/or Drop Changes

Interactively 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.

Example

Interactively modify the most recent three local commits.

git rebase -i -r HEAD~3

Clean Up Repository

Clean the repository of orphaned commits.

git reflog expire --expire-unreachable=now --all
git gc --prune=now

NOTE: 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 Commits for Text

Search commit changes for specified text.

git log -S "<text>" --source --all

NOTE: The <text> parameter is the text to be searched for.

Example

Search commit changes for "Hello world".

git log -S "Hello world" --source --all

List Changed Files - with Status

List 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.

List Only Files Added

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.

Print Number of Files in Commit

List the number of files changed in a specified commit.

git log --oneline --name-status <commit_hash> -1 | wc -l

NOTE: The <commit_hash> parameter is the hash of the commit whose files should be listed.
NOTE: The commit hash can be abbreviated.

Point Branch HEAD to Commit

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.

Example

Change the head of the main branch to the specified commit.

git checkout dev
git branch -f main ABCDEF

Initialize and Update All Submodules

Initialize and update all submodules, recursively.

git submodule update --init --recursive

Add Submodule

Add 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.

Example

Add Jekyll as a submodule to the current repository.

git submodule add git@github.com:jekyll/jekyll.git

Remove Submodule

Remove 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