Skip to content

Instantly share code, notes, and snippets.

@berndbausch
Last active March 23, 2018 04:42
Show Gist options
  • Save berndbausch/fccd1c0a8185f373666accc1450b4b65 to your computer and use it in GitHub Desktop.
Save berndbausch/fccd1c0a8185f373666accc1450b4b65 to your computer and use it in GitHub Desktop.

Commands

git init creates repo

git add stages files

git commit commits staged files to the repo.

Why two steps staging and committing? The separation of staging and committing allows me to control the scope of each commit. I can stage a group of files that belongs together, one after the other, then commit that group.

git commit -m MESSAGE includes message. Without -m: message added via editor.

git status reports:

  • staged changes that have not been committed yet
  • modifications that have not been staged yet

Note: The same file may be reported twice as not staged and not committed.

git log lists commits. Very fine-grained filtering and formatting:

  • git log --pretty=oneline
  • git log --since="5 min ago"
  • git log --since=yesterday
  • git log --pretty=format:FORMAT_STRING, where %h hash, %d decorations e.g. branch heads or tags, %a author date, %an author name, %s comment

Aliases in $HOME/.gitconfig, e.g.

		[alias]
		br = branch
		hist = log --pretty=format:'%h %ad | %s%d [%an]' --graph --date=short

git checkout HASH resets all files to the status of the commit identified by HASH. Creates "detached HEAD" state, i.e. I am not on any branch.

git checkout BRANCH e.g. git checkout master. Leaves detached HEAD state and goes back to the lastest version in this branch.

Commit references commits can be referred to by absolute hash, absolute tag, relative to a hash or tag. ref^ means parent state of ref, ref~3 means great-grandparent state of ref etc.

git tag name adds a human-readable name to current version

git tag lists all current tags. Tags also show up in the decorations (%d) of logs

git tag -d TAGNAME deletes a tag

git reset HEAD esets the staging area to be whatever is in HEAD. This clears the staging area of uncommitted changes. It does not reset changes in the working directory, i.e. files.

git reset REF sets the pointer to the reference in the branch. Optionally adjusts staging area and file contents in the working directory.

git reset REF --hard also "forgets" about all the commits more recent than REF. However, tagged commits and their ancestors are still in the repo and can be seen with git log --all.

git revert HEAD adds a "revert commit", which puts the files back to the state before the lastest commit. Rather than HEAD, I can revert to any other commit, e.g. HEAD~2. However, this may lead to merge conflicts .

Workflows

  • Go to an earlier commit
  • Go back to the lastest state of the main branch
  • List commits
  • Undo unwanted changes before committing in case the changes are not staged yet:
	git status 						# check if staged or not
	git checkout FILE1 FILE2 ...  	# undo changes in file(s)
	git status						# should be back on master
  • Undo unwanted changes before committing in case changes are staged but not committed:
	git status 						# check if staged but not committed
	git reset HEAD FILE1 FILE2 ...  # resets staging area, but not the files
	git status						# shows that there are unstaged changes
	git checkout FILE1 FILE2 ...
	git status
  • Undo commits requires another commit that undoes the unwanted commit (makes sense?). I.e. I don't throw the unwanted commit away, but I add another commit that puts my files in the earlier state.
    git revert HEAD		# adds a commit that goes back to earlier state
    git log --max-count=3 --pretty=oneline
    fff4e0d34f35ff4143b9f1b920476c93fcebd7f2 Revert "committed by mistake"
    933f0028fe331514c4d9cfc625ddef447f36cf93 committed by mistake
    cd8be0cee8d0a6d313d439c9b3f6117c42b8a938 comment added
  • REALLY undo commits, i.e. remove the commit from the chain. The commits are still in the repo, but the only way to reference them is by their hash. The secret lies in the --hard option.
    git reset REF --hard
    git log		# everything more recent than REF is gone
  • REALLY undo commits with an emergency exit. When a commit is tagged, even a hard reset still keeps it and its successors in the log. Removing the tag will then remove the commit from the log.
    git tag unwanted_commit
    git reset earlier_commit --hard
    git log                            # everything younger than earlier_commit is gone
    git log --all	               # but not quite
    git tag -d unwanted_commit
    git log --all                      # after deleting the tag, it's really gone
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment