Some notes on git
This set of notes covers the main things that I think you need to know about working with git. It is not comprehensive and mainly serves as a reminder for myself.
Remotes
In a typical open source workflow using GitHub or BitBucket, you would fork the main repository into your own and then clone that copy to your local computer:
git clone git@github.com:akrabat/joind.in.git
You then need to connect your local repository to the main repository. By convention, the main repository is known as upstream:
cd joind.in git remote add upstream git://github.com/joindin/joind.in.git
To sync your local repository with upstream and update your copy back on BitBucket/GitHub:
git checkout master git fetch upstream git merge --ff-only upstream/master git push origin
If the merge fails, then something bad has happened and you’ll need Google! One option is to force your master to match upstream using git reset --hard upstream/master and then git push --force origin.
Branching
The main branch in the repository is called master. Never ever code directly on master. Always create a branch and code on that and then merge back to master when complete.
(Note that the push command is also used throughout this document to sync your local repository with your remote on BitBucket/GitHub. If don’t want to publish, then don’t push.)
Create a branch:
git checkout -b my-branch-name git push origin my-branch-name
List all branches:
git branch -v
To list all remote branches too use the -a switch:
git branch -v -a
Change from one branch to another:
git checkout another-branch-name
Delete a branch:
git branch -D my-branch-name git push origin :my-branch-name
Rebase master onto a branch:
If lots of people are working on the project, then master has probably changed a lot since you started. It’s going to make your merge back to master much easier if you update your branch so that all your changes appear to be after all the changes on master. This is known as rebasing:
git fetch upstream git checkout my-branch-name git rebase -f upstream/master git push -f origin my-branch
Bring in a remote branch to your local repository:
If you want to work with a branch that’s on a remote repository, then you need to create your own tracking branch:
git fetch upstream git checkout master git branch -t upstream/remote-branch-name git push origin remote-branch-name
The name of your local branch will match the remote branch name.
Sync remote branch with local one
git fetch upstream git checkout remote-branch-name git merge upstream/remote-branch-name git push origin
Committing
To commit a change:
To commit a change, you first need to stage the files that you want to commit to the index:
git add filename
You can then commit:
git commit -m "my commit message" git push origin
Note that if you change a filename after adding to the index, then the change will not be committed unless your git add the file again. For information about a good commit message, read A Note About Git Commit Messages by Tim Pope.
Merging
Merge a branch into master:
git checkout master git fetch upstream && git merge --ff-only upstream/master git merge --no-ff my-branch-name
Note that you don’t need to commit anything. You do need push though:
git push
If there were conflicts, then you need to resolve them by editing the files appropriately (look for <<<<<<<). At this point, you do need commit your changes:
git add . git commit git push
Back out a conflicted merge:
git reset --hard HEAD
Working with your repository
To find out what’s happened:
git reflog -10
This provides a list of the last 10 things that you’ve done on this repository across all branches.
git log --oneline -10
This provides a list of the last 10 commits that’s happened on this branch
In both cases, the first column contains the commit hash reference that uniquely identifies each commit.
To find out current commit:
git log -1
To undo all working changes
git checkout .
To revert a commit:
Find the commit that you want to go back to via log or reflog:
git reset --hard abcdef0
You can also use the ‘HEAD’ number from reflog:
git reset --hard HEAD@{1}
To amend last commit message:
git commit --amend -m "New commit message"
It’s best to do this before pushing. If you have pushed, then you need to force push using git push --force and expect to get lots of hassle from your co-workers.
Differences
To find out the differences between your edits and the last commit:
All files:
git diff
One file:
git diff -- my-filename
To find out the differences between current branch and master:
git diff master..HEAD my-filename
To find out the differences between local master and origin’s master:
git diff HEAD...origin/master
Some git aliases
Aliases provide a way to create new git commands and are usually used for creating shortcuts:
Type these from the command line:
$ git config --global alias.st status $ git config --global alias.staged 'diff --staged' $ git config --global alias.unstage 'reset HEAD --' $ git config --global alias.last 'log -1 HEAD'
This gives you some new git commands:
- git st => view current status
- git staged => view the diff of what is currently staged
- git unstage filename => Remove filename from the staging area
- git last => view last commit
Nice list. I also like "git remote -v" to quickly list the remotes I have.
Just curious, but why not use
git diff master…origin/master
to get diff between master and origin? Your command may show differences between whatever branch you have checked out and origin, right? I also suggest having an alias for syncing your master, origin/master and upstream/master in one command.
Good Article
Keep writing
Thanks…
Better add –replace-all option to avoid recursion when run a second time.
Try with: git config –global alias.staged 'diff –staged'
Also, Windows requires double quotes for multi-word parameters.
Examples:
git config –global –replace-all alias.st status
git config –global –replace-all alias.bra branch
git config –global –replace-all alias.com commit
git config –global –replace-all alias.staged "diff –staged"
git config –global –replace-all alias.unstage "reset HEAD –"
git config –global –replace-all alias.last "log -1 HEAD"