git
This page is designed to unify all the tips and tricks associated with using git. Please feel free to modify and update as needed.
- Commits
- Checkout
- Branching
- Clean
- Diff
- Excluding files
- Forking
- .gitignore
- Merge conflicts
- Undoing commits
- Other Configurations
Commits
Amending a Commit Message
Changing a commit message can cause lots of problems if not handled correctly. Only use the following if absolutely necessary.
Local commits
To open your editor, allowing you to change the commit message of the most recent commit:
git commit --amend
Additionally, you can set the commit message directly in the command line with:
git commit --amend -m "New commit message"
…however, this can make multi-line commit messages or small corrections more cumbersome to enter.
Remote commits
Changing the message of a commit that you’ve already pushed to your remote branch
Warning: be cautious about amending commits that you have already shared with other people. Amending commits essentially rewrites them to have different SHA IDs, which poses a problem if other people have copies of the old commit that you’ve rewritten. Anyone who has a copy of the old commit will need to re-synchronize their work with your newly re-written commit, which can sometimes be difficult, so make sure you coordinate with others when attempting to rewrite shared commit history, or just avoid rewriting shared commits altogether.
If you’ve already pushed your commit up to your remote branch, then you’ll need to force push the commit with
git push <remote> <branch> --force
Or
git push <remote> <branch> -f
Warning: force-pushing will overwrite the remote branch with the state of your local one. If there are commits on the remote branch that you don’t have in your local branch, you will lose those commits.
Past Commits
You can use rebase to edit a past commit by passing the commit hash, with the following:
git rebase -i '<commit-hash>^'
Once your editor is opened with the rebase dialog, put edit as the action word for that commit. Save and close. Open the project and make the changes you wanted to update to that commit. To keep the same commit message you have previously use:
git commit --all --amend --no-edit
Now you can use
git rebase --continue
git push -f
Checkout
To check out a file form another branch:
git checkout <src-branch> -- <path/to/file>
Branching
- Resetting local branch to match remote
- Deleting a remote branch
- Local branches
- Delete all local branches except main
- References to remote branches
- Remote branches
I follow git branching naming convention outline in this gist
List all branches including remotes
git branch -a
Resetting local branch to match remote
Back to main header: Branching
Setting your branch to exactly match the remote branch can be done in two steps:
git fetch origingit reset --hard origin/master
If you want to save your current branch’s state before doing this (just in case), you can do:
git commit -a -m "Saving my work, just in case"git branch my-saved-work
Deleting a remote branch
Back to main header: Branching
git push origin :<branch-name>
Local branches
Back to main header: Branching
Sourced From: Git housekeeping tutorial
At first, list all local branches:
git branch
We need to know what branches are already merged in “master” and can be easily removed:
git checkout mastergit branch --merged
Now, remove all outdated branches with:
git branch -d <branch-name-old-merged-feature>
Next, decide what to do with not merged branches:
git branch --no-merged
If some of them is just abandoned stuff that you don’t need anymore, remove it with “-D” option:
git branch -D old-abandoned-feature
Delete all local branches except main
Back to main header: Branching
You can do a dry run to see all branches this command will delete first by running the following:
git branch | grep -v $(git_main_branch)
If this matches what you are looking to delete, you can run the following to actually delete the branch.
git branch | grep -v $(git_main_branch) | xargs git branch -D
References to remote branches
Back to main header: Branching
After each git pull or git fetch command Git creates references to remote branches in local repository, but doesn’t clean up stale references.
List referenced remote branches:
git branch -r
Clean-up outdated references:
git remote prune origin
Remote branches
Back to main header: Branching
Usually, remote repository is a big garbage heap of stale branches, if there is no responsible housekeeping person.
After previous
git remote prune origin
At first, we can find branches which are already merged in “master”:
git checkout master$ git branch -r --merged
But this command does not provide much information. What if this branch is merged, but still used for feature development. Would be cool to know last commit date and author.
This magic snippet provides all required information:
for branch in `git branch -r --merged | grep -v HEAD`; do echo -e `git show --format="%ci %cr %an" $branch | head -n 1` \\t$branch; done | sort -r
Now, you can delete own remote branches, and ask other authors to clean-up theirs:
git push origin --delete branch-name
Similar snippet for not merged branches:
for branch in `git branch -r --no-merged | grep -v HEAD`; do echo -e `git show --format="%ci %cr %an" $branch | head -n 1` \\t$branch; done | sort -r
This list should be reviewed more thoroughly to avoid losing important commits.
Clean
Perform a “dry run” of
git clean
git clean -n
Remove untracked files from the current directory. The
-f
git clean -f
Remove untracked files, but limit the operation to the specified path.
git clean -f <path>
Remove untracked files and untracked directories from the current directory.
git clean -df
Remove untracked files from the current directory as well as any files that Git usually ignores.
git clean -xf
Example
- Edit some existing files
- Add some new files
- Realize you have no idea what you’re doing
Undo changes in tracked files
git reset --hard
Remove untracked files
git clean -df
Diff
Simply use
git diff
git diff FILE_NAME
If you need to verify the difference of a file that is already staged use the following.
git diff --staged FILE_NAME
If you you want to diff two branches use the following.
git diff main...develop# or to compare with the current branch simplygit diff OTHER_BRANCH_NAME
You can also use some useful flags with this command if the output it to great.
- to see only the file names.--name-only
- add this to the end if you want to check only a particular file or directory.-- fileOrDirectory
Git diff with opendiff
mkdir ~/bin/touch ~/bin/git-diff.sh
The contents of the file will look like this:
#!/bin/sh/usr/bin/opendiff "$2" "$5" -merge "$1"
Once the script has been made, you’ll want it to be executable
chmod u+x ~/bin/git-diff.sh
Finally, tell git that you want to set it up as your default merge tool:
git config --global diff.external ~/bin/git-diff.sh
If you later decide you hate it, run this command to go back:
git config --global --unset diff.external
Excluding files
Ignoring tracked files in your local repo
git update-index --skip-worktree SOME_FILE
or
git update-index --assume-unchanged SOME_FILE
To undo assume unchanged
git update-index --no-assume-unchanged SOME_FILE
If using
assume-unchanged
This will allow you to use the alias
git ignored
[alias]ignored = !git ls-files -v | grep "^[[:lower:]]"
Ignoring un-tracked files in your local repo
Untested
If you ever want to ignore a file from git, but don’t want to add it to the .gitignore file, you can do it on your local copy by adding it to the file .git/info/exclude
I’ve setup an alias to do so, just add this to your .gitconfig file under the
[alias]
exclude = !sh -c 'echo "$1" >> .git/info/exclude' -
Then you can execute:
git exclude SOME_FILE
Forking
When needing to work with a new branch on a forked repo you have to create a new branch in your local fork that references that branch. This can be accomplished by:
git remote add theirUsername git@github.com:theirUsername/repoName.gitgit fetch theirUsernamegit checkout -b my_name_for_their_branch theirUsername/theirBranch
Example
Following directions for Keeping your fork in sync for the DevCetner.
In this example I will be demonstrating creating a
GA
upstream
GA
upstream
You can set
upstream
git remote add upstream git@github.ibm.com:MFPSamples/DevCenter
Once this is done your are free to
fetch
pull
upstream
git fetch upstreamgit merge upstream/master
Note: This is assuming you are trying to merge to you local (forked)
master
If you need to work off a branch that is in the
upstream
git checkout -b ENG-GA upstream/GA
This line creates a local branch
ENG-GA
upstream/GA
ENG-GA
upstream/GA
upstream/GA
git fetch upstreamgit merge upstream/GA
Once you are ready to submit your changes back to upstream you can create a pull request via github.com. Ensuring that your base branch is
GA
ENG-GA

.gitignore
Untracking a single file
To untrack a single file that has already been added/initialized to your repository, i.e., stop tracking the file but not delete it from your system use:
git rm --cached filename
Untracking all files
To untrack every file that is now in your .gitignore:
-
Commit any outstanding code changes, and then, run this command:
git commit -m "Commit message" -
This removes any changed files from the index(staging area), then just run:
git rm -r --cached . -
Add all tracked changes
git add . -
Commit it:
git commit -m ".gitignore is now working"
Merge conflicts
Local changes to same files
To resolve merge conflicts with error.
error: Your local changes to the following files would be overwritten by merge:
To stash entire working tree
git stash save --keep-index
Now you will be able to merge branch successfully
If you do not need your local changes you can simple drop the stash
git stash drop
or…if you need your changes you can attempt to process them in now using pop
git stash pop
To show what is in your stash use show
git stash show
Undoing commits
git commit -m "Something terribly misguided"git reset --soft HEAD~# << edit files as necessary >>git add ...git commit -m "New commit message"git commit -c ORIG_HEAD
Delete the most recent commit, keeping the work you’ve done:
git reset --soft HEAD~1
Delete the most recent commit, destroying the work you’ve done:
git reset --hard HEAD~1
Other Configurations
git config --global core.trustctime false