{ "type": [ "h-entry" ], "properties": { "name": [ "Aha! Moments When Learning Git" ], "published": [ "2011-06-23T08:24:19Z" ], "category": [ "git", "guide", "tips", "via-pinboard" ], "bookmark-of": [ { "type": [ "h-cite" ], "properties": { "url": [ "http://betterexplained.com/articles/aha-moments-when-learning-git/" ], "name": [ "Aha! Moments When Learning Git" ], "content": [ { "value": "
Git is a fast, flexible but challenging distributed version control system. Before jumping in:
\n\nAlong with a book, tutorial and cheatsheet, here are the insights that helped git click.
\nGit has a staging area. Git has a staging area!!!
\nYowza, did this ever confuse me. There's both a repo (\"object database\") and a staging area (called \"index\"). Checkins have two steps:
\ngit add foo.txt
\ngit commit -m \"message\"
\ngit add --update\"
to stage all tracked, modified filesWhy stage? Git's flexible: if a, b and c are changed, you can commit them separately or together.
\nBut now there's two undos:
\ngit checkout foo.txt
\ngit reset HEAD foo.txt
\nAdd and commit, add and commit -- Git has a rhythm.
\nBranches are like \"Save as...\" on a directory. Best of all:
\nWhy branch? Consider the utility of \"Save as...\" for regular files: you tinker with multiple possibilities while keeping the original safe. Git enables this for directories, with the power to merge. (In practice, svn is like a single shared drive, where you can only revert to one backup).
\nI see branches as \"virtual directories\" in the .git folder. While inside a physical directory (c:\\project or ~/project), you traverse virtual directories with a checkout.
\ngit checkout master
\ngit branch dev
\ngit merge dev
\ngit branch
\nMy inner dialogue is \"change to dev directory (checkout)... make changes... save changes (add/commit)... change to master directory... copy in changes from dev (merge)\".
\nThe physical directory is a scratchpad. Virtual directories are affected by git commands:
\nrm foo.txt
\ngit rm foo.txt
\nJust like seeing your current directory, put the current branch in your prompt!
\n\nIn my .bash_profile:
\nparse_git_branch() {\n git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* (.*)/(1)/'\n}\n\nexport PS1=\"[33[00m][email protected][33[01;34m] W [33[31m]$(parse_git_branch) [33[00m]$[33[00m] \"\n
\nGit leaves branch organization to you. Nvie.com has a great branch strategy:
\n\nStay sane by choosing a branch layout up front. I have a master tracking a svn project, and dev for my own code. In general, master is clean so I can branch anytime for one-off fixes.
\nGit has local and remote commands; seeing both confused me (\"When do you checkout vs. pull?\"). Work locally, syncing remotely as needed.
\nLocal data
\ngit init
\nRemote data
\ngit remote add name path-to-repo
\ngit branch -a
\ngit clone path-to-repo
\ngit pull
\ngit push
\nWhy local and remote? Subversion has central checkins, so you avoid committing unfinished work. With git, local commits are frequent and you only push when ready.
\nGit addresses information by a hash (GUID) of its contents. If two branches are the same, they have the same GUID (and vice versa).
\nWhy's this cool? We can create branches independently, merge them, and have a common GUID. No central numbering needed. Usually, we just compare the first few digits: \"Are you on a93?\".
\nFor your .gitconfig:
\n[alias]\n ci = commit\n st = status\n co = checkout\n oneline = log --pretty=oneline\n br = branch\n la = log --pretty=\"format:%ad %h (%an): %s\" --date=short\n
\nThere are some GUI tools for git, but I prefer to learn via the command line. Git is opinionated software (which I like), and analogies help me understand its world view.
\nGit is a fast, flexible but challenging distributed version control system. Before jumping in:
\n\nAlong with a book, tutorial and cheatsheet, here are the insights that helped git click.
\nGit has a staging area. Git has a staging area!!!
\nYowza, did this ever confuse me. There's both a repo (\"object database\") and a staging area (called \"index\"). Checkins have two steps:
\ngit add foo.txt
\ngit commit -m \"message\"
\ngit add --update\"
to stage all tracked, modified filesWhy stage? Git's flexible: if a, b and c are changed, you can commit them separately or together.
\nBut now there's two undos:
\ngit checkout foo.txt
\ngit reset HEAD foo.txt
\nAdd and commit, add and commit -- Git has a rhythm.
\nBranches are like \"Save as...\" on a directory. Best of all:
\nWhy branch? Consider the utility of \"Save as...\" for regular files: you tinker with multiple possibilities while keeping the original safe. Git enables this for directories, with the power to merge. (In practice, svn is like a single shared drive, where you can only revert to one backup).
\nI see branches as \"virtual directories\" in the .git folder. While inside a physical directory (c:\\project or ~/project), you traverse virtual directories with a checkout.
\ngit checkout master
\ngit branch dev
\ngit merge dev
\ngit branch
\nMy inner dialogue is \"change to dev directory (checkout)... make changes... save changes (add/commit)... change to master directory... copy in changes from dev (merge)\".
\nThe physical directory is a scratchpad. Virtual directories are affected by git commands:
\nrm foo.txt
\ngit rm foo.txt
\nJust like seeing your current directory, put the current branch in your prompt!
\n\nIn my .bash_profile:
\nparse_git_branch() {\n git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* (.*)/(1)/'\n}\n\nexport PS1=\"[33[00m][email protected][33[01;34m] W [33[31m]$(parse_git_branch) [33[00m]$[33[00m] \"\n
\nGit leaves branch organization to you. Nvie.com has a great branch strategy:
\n\nStay sane by choosing a branch layout up front. I have a master tracking a svn project, and dev for my own code. In general, master is clean so I can branch anytime for one-off fixes.
\nGit has local and remote commands; seeing both confused me (\"When do you checkout vs. pull?\"). Work locally, syncing remotely as needed.
\nLocal data
\ngit init
\nRemote data
\ngit remote add name path-to-repo
\ngit branch -a
\ngit clone path-to-repo
\ngit pull
\ngit push
\nWhy local and remote? Subversion has central checkins, so you avoid committing unfinished work. With git, local commits are frequent and you only push when ready.
\nGit addresses information by a hash (GUID) of its contents. If two branches are the same, they have the same GUID (and vice versa).
\nWhy's this cool? We can create branches independently, merge them, and have a common GUID. No central numbering needed. Usually, we just compare the first few digits: \"Are you on a93?\".
\nFor your .gitconfig:
\n[alias]\n ci = commit\n st = status\n co = checkout\n oneline = log --pretty=oneline\n br = branch\n la = log --pretty=\"format:%ad %h (%an): %s\" --date=short\n
\nThere are some GUI tools for git, but I prefer to learn via the command line. Git is opinionated software (which I like), and analogies help me understand its world view.
\n