Main Page - Log in -

Git notes

From Noah.org

Jump to: navigation, search


Contents

git notes

Git is my current favorite VCS (or RCS or SCCS or SCMS or VC or whatever). I'm trying to phase out Subversion in favor of Git. Subversion is fundamentally flawed. What it does do it does well, but it does not do things in a way that makes sense (to me). It's slow and uses a lot of disk space. In the past I discounted the disk space wasting as irrelevant because storage is cheap, but now I've changed my mind. There have been many times when all that wasted disk space was a problem.

Kernel.org git QuickStart

git remote

When using git-remote over ssh it seems that you have to use the full path on the remote server, and not the path relative to the user you are connecting as. Also, you must put a trailing slash on the path. For example:

git ls-remote ssh://username@www.example.org/home/username/repositorium/engineering/

convert clean repository to 'bare'

git config --bool core.bare true

Or do this:

git reset --hard HEAD

When pushing to a remote repository that you have cloned from you might get an error like this:

remote: error: refusing to update checked out branch: refs/heads/master
remote: error: By default, updating the current branch in a non-bare repository
remote: error: is denied, because it will make the index and work tree inconsistent
remote: error: with what you pushed, and will require 'git reset --hard' to match
remote: error: the work tree to HEAD.

Converting the remote repository to a bare repository will fix this.

git clone

git clone
git fetch
git pull

config

git config --global user.name "Noah Spurrier"
git config --global user.email noah@noah.org
git config --global core.editor vim
git config --global color.ui auto
git config --global merge.tool vimdiff

git archive

This is like an export. It retrieves a remote git repository without the .git metadata (history).

git archive --remote=ssh://username@www.example.org/home/username/repositorium/engineering/ HEAD > git_archive.tar

You can also use this to retrieve subdirectories of repositories. The follow retrieves only the subdirectory "dotfiles". Note that the selection of subdirectory is made after HEAD::

git archive --remote=ssh://username@www.example.org/home/username/repositorium/engineering/ --prefix=dotfiles/ HEAD:dotfiles > dotfiles_archive.tar

fix commits with the wrong committer/author name or email address

This basically completely rewrites your history. All of your git hashes will change.

git filter-branch --env-filter 'GIT_AUTHOR_NAME="Noah Spurrier";GIT_AUTHOR_EMAIL="noah@noah.org";GIT_COMMITTER_NAME="Noah Spurrier";GIT_COMMITTER_EMAIL="noah@noah.org";' HEAD

Git Commit: git/svn commit differences are confusing to newbies

Do a `git commit -a` in most cases.

Git stages commits into an index before they are committed, so a commit is a two step process. The `git-status` command will show which modifications have been indexed for the next commit. The `git-add` command will index a modified or new file for the next commit.

A `git fetch` also is done as a two step process. I especially like this feature. When you do a `git fetch` files are pulled from a remote server, but they are not immediately merged into your working copy. I despise this about SVN. Instead the remote files (actually their diffs) are held in the index where you can browse them and choose which parts to merge into your working copy.

Notice that the message below from `git-status` says two things. It shows files that have been modified and it shows which of those changes have been added to the commit. Notice here that one file is modified, but no changes have actually been added to the commit.

$ git-status
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#
#       modified:   dotfiles/.vimrc
#
no changes added to commit (use "git add" and/or "git commit -a")

You can have git automatically index all modified files with `git commit -a`. This is usually what most SVN users expect.

git-svn

dcommit

  1. When you want to do "svn up", instead do "git svn rebase". If you have conflicts use `git mergetool` then `git rebase --continue`.
  2. When you have everything up-to-date do `git svn dcommit`.
  3. If git complains about files not being up-to-date do `git svn rebase` again.

VCS command translation

See also this table in Wikipedia: VCS commands

Rosetta table gives git and Subversion equivalent commands
git subversion notes
git clone url svn checkout url `git+ssh` works just like `svn+ssh`
git clone git+ssh://noah@www.example.org/home/noah/src
git pull svn update
git status svn status The output from git is more clear.
git -f checkout path svn revert path This deletes your local changes.
git add file svn add file
git rm file svn rm file
git mv file svn mv file
git commit -a svn commit
git log svn log
git show rev:path/to/file svn cat url
git show rev:path/to/directory svn list url
git show rev svn log -rrev url
git branch branch_name svn copy http://example.com/svn/trunk http://example.com/svn/branches/branch_name
git merge --no-commit branch_name svn merge -r 20:HEAD http://example.com/svn/branches/branch_name This is reason #1 why SVN sucks. Merge tracking is crap. As of version 1.5 they have some limited support for merge tracking, but it still blows.
git tag -a tag_name svn copy http://example.com/svn/trunk http://example.com/svn/tags/tag_name SVN doesn't really have tags. Most people just use copy. The downside is that people can commit to tags, which kind of defeats the purpose.

Cheat Sheet

Originally from http://cheat.errtheblog.com/s/git

Setup


git clone <repo>

 clone the repository specified by <repo>; this is similar to "checkout" in
 some other version control systems such as Subversion and CVS

Add colors to your ~/.gitconfig file:

  [color]
    ui = auto
  [color "branch"]
    current = yellow reverse
    local = yellow
    remote = green
  [color "diff"]
    meta = yellow bold
    frag = magenta bold
    old = red bold
    new = green bold
  [color "status"]
    added = yellow
    changed = green
    untracked = cyan

Highlight whitespace in diffs

  [color]
    ui = true
  [color "diff"]
    whitespace = red reverse
  [core]
    whitespace=fix,-indent-with-non-tab,trailing-space,cr-at-eol

Add aliases to your ~/.gitconfig file:

</pre>

 [alias]
   st = status
   ci = commit
   br = branch
   co = checkout
   df = diff
   lg = log -p
   lol = log --graph --decorate --pretty=oneline --abbrev-commit
   lola = log --graph --decorate --pretty=oneline --abbrev-commit --all
   ls = ls-files

</pre>

Configuration


git config -e [--global]

 edit the .git/config [or ~/.gitconfig] file in your $EDITOR

git config --global user.name 'John Doe' git config --global user.email johndoe@example.com

 sets your name and email for commit messages

git config branch.autosetupmerge true

 tells git-branch and git-checkout to setup new branches so that git-pull(1)
 will appropriately merge from that remote branch.  Recommended.  Without this,
 you will have to add --track to your branch command or manually merge remote
 tracking branches with "fetch" and then "merge".

git config core.autocrlf true

 This setting tells git to convert the newlines to the system’s standard
 when checking out files, and to LF newlines when committing in

You can add "--global" after "git config" to any of these commands to make it apply to all git repos (writes to ~/.gitconfig).


Info


git reflog

 Use this to recover from *major* fuck ups! It's basically a log of the
 last few actions and you might have luck and find old commits that
 have been lost by doing a complex merge.

git diff

 show a diff of the changes made since your last commit
 to diff one file: "git diff -- <filename>"
 to show a diff between staging area and HEAD: `git diff --cached`

git status

 show files added to the staging area, files with changes, and untracked files

git log

 show recent commits, most recent on top. Useful options:
 --color       with color
 --graph       with an ASCII-art commit graph on the left
 --decorate    with branch and tag names on appropriate commits
 --stat        with stats (files changed, insertions, and deletions)
 -p            with full diffs
 --author=foo  only by a certain author
 --after="MMM DD YYYY" ex. ("Jun 20 2008") only commits after a certain date
 --before="MMM DD YYYY" only commits that occur before a certain date
 --merge       only the commits involved in the current merge conflicts

git log [1]



-->