Below are my notes about how to use Git, which summarize the main points.
Initialize
git init
Status
git status
Add a new file or stage a change
git add filename
Add a batch of files
git add '*.txt'
Note the quotes! That way subdirectories are processed.
Unstage an add (maybe added too much stuff)
git reset filename
Effectively this removes the add from the index.
Unstage everything (maybe added too much stuff)
git reset
Effectively this removes all (staged) changes from the index.
Commit staged changes (things done with git add or git rm)
git commit -m "description"
Add and commit changes
git commit -am "description"
Amend a commit (maybe forgot to add something)
After the commit, make necessary changes (eg. add more files) then:
git commit --amend
Only do this if you haven't pushed the commit to a remote repository.
Undo the last commit (maybe staged and then committed too many files)
git reset --soft HEAD^
Only do this if you haven't pushed the commit to a remote repository.
Note that using --soft keeps the existing files with their changes since the last commit. If you use --hard instead, the working directory is changed back to how it was at the last commit.
After resetting the commit you may then need to reset individual files to unstage them (see "unstage an add" above). Alternatively do a "git reset HEAD^" instead to get the index back to how it was at the last commit. If you have already done a "git reset --soft HEAD^" then follow it by "git reset" to unstage all adds.
Undo the last commit and put the index back to where it was
git reset HEAD^
Only do this if you haven't pushed the commit to a remote repository.
Note that this keeps the existing files with their changes since the last commit. This also puts the index back to how it was, so files won't be staged any more.
Take a file back to how it was last commit
git checkout -- filename
Show log of what we did
git log
Show log of what we did for one file
git log -- filename
Show log of recent changes, one-line format, since a certain date
git log --oneline --reverse --after='1 mar'
The --reverse option shows changes in date (ascending) order.
You can specify date ranges, eg. --after='1 week ago' .
Show log of changes to the branch tip
git reflog
This gives similar output to give "git log --oneline" however it also includes merges and resets.
Push to GitHub
git push
Tag commits
git tag -ln # show tags
git tag -a tagname -m "description" # add tag
git push --tags # push to github
Fetch changes from GitHub
git fetch origin
Compare changes from GitHub
git diff origin/master
Apply changes from GitHub
git merge origin/master
Warning: It is preferable to have a clean working directory before merging, in case the changes from the merge clash with the changes in the working directory.
If you have merge conflicts
- Edit the file(s) looking for
<<<<<<< and >>>>>>> . Fix the conflicts, then do a "git add" and a "git commit".
- Or: Revert the merge with:
git merge --abort
Stash changes
This is to get back to the most recent commit, saving what we are working on. (Applies to tracked files only)
git stash
Show stashes
git stash list
Get stash back
git stash apply
Get rid of the stash
git stash drop
Show tracked files
git ls-files
Show unstaged changes
git diff
Show staged changes
git diff --staged
These are the changes if you commit without adding any more files.
Show changes if you commit with -a (to add changes)
git diff HEAD
Show changes since previous commit
git diff HEAD^
Show changes since 5 commits ago
git diff HEAD~5
Summarize changes since previous commit
git diff HEAD^ --stat
Show changes since previous commit for a certain file
git diff HEAD^ -- filename
Make a branch
git branch branchname
Warning! Commit (or stash) changes before starting on a new branch.
Switch to that branch
git checkout branchname
Merging with your new branch
Warning! First commit your changes in the new branch.
git checkout master # back to main (master) branch
git merge branchname # merge in changes
git branch -d branchname # delete the old branch (if wanted)
What is master, origin and HEAD?
What does "staged" mean?
Files can be in one of four states:
- Untracked* - git does not yet track them (eg. new files) (to change that use: git add)
- Tracked but unmodified - git tracks the file but it hasn't changed since the last commit
- Tracked and modified - git knows it has changed (use git diff, or git status to see which files are in this state)
- Tracked, modified, and staged - the file has changed and it is "staged" to go into the next commit (to stage a changed file use: git add)
A commit changes the status from "Tracked, modified, and staged" back to just "tracked but unmodified".
Note that the word index can be used to refer to the staging area. Thus help files that refer to changing the index are referring to changing the list of files that are staged.
* Untracked files can also be ignored (eg. compiler object files). This is done by putting the file name (or wildcard) into the file .gitignore
An ignored file is not reported by "git status". If it is not ignored, and not tracked, then you get a warning. This is because you may have just created a new file and actually want to track it (by doing a "git add").
An example .gitignore file might be:
.*
!.gitignore
*.obj
That file ignores all files starting with a period (except .gitignore itself) and also all files ending in .obj
Git configuration: list
git config --list # this repository (with global showing first)
git config --global --list # global configuration
If a key appears more than once (eg. global and then local) the last one is used.
Git configuration: change
git config --global user.name "Nick Gammon"
git config --global user.email nick@gammon.com.au
git config --global core.autocrlf true
git config --global core.editor "vim"
Git configuration: check an item
git config user.name
Remote management
If you did a "git init" you will not yet have a remote site. If you did a "git clone" to copy code from somewhere else, that place will be your remote site (usually known as "origin" - the origin of the source).
View remote sites
git remote -v
Add a remote site
git remote add origin https://github.com/user/repo.git # https
git remote add origin git@github.com:user/repo.git # ssh
The example above adds a site named "origin" with the specified URI as the remote site.
Remove a remote site
git remote remove git@github.com:user/repo.git
Make your own remote site
cd ~/someplace # go to where you want the repository to be
git init --bare repo.git
You could use the above to make a "bare" repository (like GitHub is) to which you can push changes. This could, for example, be on a backup or network disk.
Clone from a remote site
git clone git@github.com:user/repo.git
This makes a copy (clone) of the repository (repo) from GitHub for the nominated user. You can then view the history of the source, and make local changes.
For example, to clone my Regular Expression library:
git clone git@github.com:nickgammon/Regexp.git # clone it
cd Regexp # enter new repository
git remote -v # show remote info
origin git@github.com:nickgammon/Regexp.git (fetch)
origin git@github.com:nickgammon/Regexp.git (push)
git log --oneline
05e77b2 Create README.md
13b6415 Initial commit
2fef51d Initial commit
ca1fa03 Got rid of two compiler warnings
cc9a494 Added replacing, counting, examples
dc82e30 Added helper functions, cleaned up source
d78e10c Fixed spelling of Arduino
This example shows how we can get a copy of a repository, and then confirm where it came from. Then we can find the commit log.
Make an archive of a repository
git archive master --output=../filename.tgz
This makes a compressed tar file of the current repository. The output type is inferred from the output filename (eg. .tgz or .zip). This is handy for distributing your repository without all the git history attached to it (ie. without the .git subdirectory). You can specify a subdirectory if you only want part of the repository, eg.
git archive HEAD --output=../filename.zip examples
|