Git Cheatsheet with a few nifty tips and tricks
- Git log (Pretty graph view)
- Stash
- Cherry pick and apply to current branch
- Forget added files in git
- Git Aliases
- Deleting a branch both locally and remotely
- Keeping a forked repo in sync with the main repo
- Different branch name for local and remote
- Squash PR commits into one
- Bumping version and publishing upstream's branch (when you already have a fork)
- Test a pull request in your local before merging
- Deleting last commit from git
- Fetch all Git branches from remote
- Fetch a branch from someone else's fork
- Deleting branch from fork and then re-creating it with same from upstream
git log --graph
This displays your commits in a nice tree form.
By making the following alias you get:
- colors
- graph of commits
- one commit per line
- abbreviated commit IDs
- dates relative to now
- commit references
- author of the commit
- And the alias is:
git config --global alias.lg "log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative"
And every time you need to see your log, just type in
git lg
or, if you want to see the lines that changed
git lg -p
git stash
: Stash current changes
git stash save "appropriate caption here"
: Name stashed changes
git stash apply
: Apply the last stashed item
git stash pop
: Apply and drop most recent stash
git stash list
: List all stashes
git stash clear
: Clear all entries in stash
git cherry-pick ###SHA-1##
In cases picking one single commit is not enough and you need, let's say three consecutive commits - rebase is the right tool, not cherry-pick.
git rm -r --cached .
git add .
git config --global alias.<handle> <command>
git config --global alias.st status
git config --global alias.l "log --oneline --graph"
git branch -D local_branch_name
-D
force deletes, -d
will give you a warning if it’s not already merged in.
We also delete the remote branch by simply adding the "-r" flag to the "-d" option
git branch -dr origin/remote_branch_name
(or)
git push origin --delete remote_branch_name
(or)
git push origin :remote_branch_name
Keeping a forked repo in sync with the main repo (Command line/Github)
Add the remote, call it "upstream":
git remote add upstream <path-to-the-main-repo>
Fetch all the branches of that remote into remote-tracking branches, such as upstream/master:
git fetch upstream
Make sure that you're on your master branch:
git checkout master
Rewrite your master branch so that any commits of yours that aren't already in upstream/master are replayed on top of that other branch:
git rebase upstream/master
If you've rebased your branch onto upstream/master you may need to force the push in order to push it to your own forked repository.
git push -f origin master
Branch out locally:
git checkout -b local_branch_name
Checkout branch with an easy to remember local_branch_name
Push to remote & set upstream:
git push -u origin local_branch_name:remote_branch_name
Push the local branch to remote repo with a different descriptive name remote_branch_name
git branch --set-upstream-to=origin/remote_branch_name
Set your push.default to upstream to push branches to their upstreams (which is the same that pull will pull from), rather than pushing branches to ones matching in name (which is the default setting for push.default, matching).
git config push.default upstream
Fetch from upstream (when merging clone to main upstream branch) or origin (when merging branch to master)
git fetch upstream
git checkout mybranch
git merge upstream/master
If necessary, resolve conflicts and git commit...
git reset --soft upstream/master
git commit -am 'Some cool description for a single commit'
git push --force-with-lease
More on --force-with-lease
option here. Note that it's super important that you merge before resetting, and that the argument is the same master branch. Otherwise you risk messing up your local history.
The --soft parameter tells Git to reset HEAD to another commit, but that’s it. If you specify --soft Git will stop there and nothing else will change. What this means is that the index and working copy don’t get touched, so all of the files that changed between the original HEAD and the commit you reset to appear to be staged.
Extra: To squash last few commits (eg. last 2 commits) use git reset --soft HEAD~2
Fetch all the upstream branches
git fetch upstream && git reset --hard upstream/master
Lists all the remote branches
git branch -v -a
From that list choose whichever branch you need to checkout
git checkout remotes/upstream/master
In the message being shown - verify to make sure the HEAD is at the most recent commit in that branch. Example shown below
HEAD is now at 8c9d3eb... 6.3.1
➜ user git:(8c9d3eb)
Now bump the package.json version
npm version patch
You'll need to push it to remote upstream along with the tags.
git push upstream HEAD:master && git push upstream --tags
Finally, publish the package
npm publish
IMPORTANT: HEAD is now in a detatched state. So without fail switch back to your working branch!
git checkout develop
git fetch origin pull/{pull-request-id}/head:{local-branch-name-to-test}
git checkout {local-branch-name-to-test}
{pull-request-id}
can be obtained from the pull request url repo-url/pull/pull-request-id
format
If you already pushed, use git revert
If no one else is using your branch:
git reset —hard HEAD~1 (or) git reset —hard <sha1-commit-id>
git push origin HEAD —force
You will need to create local branches tracking remote branches.
Assuming that you've got only one remote called origin, this snippet will create local branches for all remote tracking ones:
for b in `git branch -r | grep -v -- '->'`; do git branch --track ${b##origin/} $b; done
After that, git fetch --all
will update all local copies of remote branches.
Also, git pull --all
will update your local tracking branches, but depending on your local commits and how the 'merge' configure option is set it might create a merge commit, fast-forward or fail.
git remote add theirusername https://github.com/theirusernam/reponame.git
git fetch theirusername
git checkout -b mynamefortheirbranch theirusername/theirbranch
Delete Local Branch
git branch -D <branch_name>
Delete Remote Branch
git push origin --delete <branch_name>
Create branch from upstream
git checkout -b <branch_name> upstream/<branch_name>
Push branch to remote
git push -u origin <branch_name>
You are in the your project directory which need use external sources!
Add / map external sources to folder <alias_name>
:
git subtree add --prefix=<alias_name> <root_project_https_url> <project_branch>
or with minimal history log:
git subtree add --prefix=<alias_name> --squash <root_project_https_url> <project_branch>
to revert some commits back (for example we need 2358acd7
commit which is behind current one in the subtree project)
git subtree merge -P <alias_name> --squash 2358acd7
to update old code in subtree from original repository
git subtree pull -P <alias_name> --squash <root_project_https_url> <project_branch>
You are in the your project directory which need use external sources!
Add / map external sources:
git submodule add <project_repo>
Pull updated code from submodule repository
git submodule update --remote
Reset submodule code to initial state
git pull --update --resource-submodules
To clone project with submodule sources
git clone --recurse <main_project_repo>
In case you've cloned project without --recurse
flag you will not have submodule data in your repository.
To load required data you need try next instruction:
git submodule update --init --recursive