June 9, 2015
Isao Yagi <[email protected]>
- local
- file at a time
- locks
Note: RCS, SCCS. Conceptually they're patching tools.
- central server
- multi-file
- merge before commit
Note: SVN, TFS: Conceptually they're meta filesystems. Path-based branching.
- distributed
- change sets
- commit before merge
Note: Git, Darcs, Bz, Hg.
- Developer's changes are kept distinct from the merge(s) they had to do to get there.
- DVCs handle more complex histories, new merging (and re-merging) scenarios, finding common ancestor...
- DVCs deal with whole trees. Path names are independent of the "branch".
Git history is a directed acyclic graph (DAG) of changes, whose nodes have globally unique identifiers.
It all made sense after I realized git is a graph manipulation tool. --paraphrased from somebody on twitter
Note: Apologies if that sounds like gibberish. There's a video of someone explaining git with tinker toys that is awesome. A good presenter would have included diagrams at least, but I'll cover the terms you will see in the docs.
- the repo is a graph (DAG)
- the nodes are commit objects
- commit objects contain these objects:
- a tree object
- blob object(s)
- possibly other tree object(s)
- a tree object
Note: tree object stores file paths, file names, permissions. Blobs contain data. Each object is referenced internally by a SHA hash. The git repo uses the filesystem as a database. Hashes used for filenames.
A Commit object consist of:
- a pointer to it's parent(s) SHA(s)
- a message
- the name/email/timestamp for author & committer
- a tree object containing blob(s) and/or tree(s)
A commit id is the SHA hash of this data. Other things point to commits, like tags, branches, or refs (i.e. head
).
Note: We can assume no commit in any repo anywhere in the world will have the same SHA, with a very very high degree of certainty. Carl Sagan number magnitude. We also have near perfect data integrity guarentees.
A lame party trick for geeks:
% mkdir foo && cd foo
% echo isao > ANY_FILENAME
% git init
% git add .
% ls .git/objects/2b/c2dbdb05e12bd7344b96329c5e89188b812a82
How do I know the name of that file?
Note: Answer 2bc2dbdb05e12bd7344b96329c5e89188b812a82
is the SHA hash of the blob isao 5<null>LF
. Git is content-addressable-- it accesses data by it's contents. Peek in .git
.
The name and email you commit as are NOT automatically related to MRGIT repo authentication.
Please do not skip this step!
git config --global user.name "Your Name"
git config --global user.email "[email protected]"
Note: you can omit the --global flag for per-repo configs.
Mac users:
git config --global credential.helper osxkeychain
Windows users: replace osxkeychain
with cache
, or store
. Best is install wincred
.
Note: store is most convenient, but keeps your password in clear text.
You should teach git to use your editor of choice.
Try:
git config --global --edit
If you can edit the configs and are happy with this, you're done. Otherwise please Google "setting up git editor X", where X is the text editor of your choice.
Mac:
git config core.autocrlf input
Windows:
git config core.autocrlf false
Everyone:
git config --global push.default simple
git config --global core.whitespace cr-at-eol
Windows users:
git config --global core.filemode false
git config --global core.ignorecase true
Note: push simple is the default in git 2.0.
To type git lf
instead of git log --graph --stat --decorate
put this in your .gitconfig
:
[alias]
lf = log --graph --stat --decorate
Bonus points for:
- mergetool
- difftool
- Use
git-bash
for all pulling and merging. - Do not use VS for merging of any kind.
Fetching: clone, fetch, pull
Getting info: status, log, diff
Manipulating: checkout, add, commit, merge
Publishing: push (this is the only command that sends changes to MRGIT)
Note: by fetching I mean getting stuff from a remote. By manipulating, I mean modifying your local repo. By publishing, I mean sharing your changes with MRGIT.
remote is a repo that is not local.
origin is the default name of the remote you cloned from. In our case it points to MRGIT.
tracking branch refers to the local (hidden) representation of a branch on a remote. i.e. origin/master
. These are updated when you fetch or pull.
You can compare and merge with the tracking branches, but they don't magically keep up to date with MRGIT.
Note: when you do a git fetch, you update the hidden tracking branches. When you see messages about "X commits ahead of" or "behind" a tracking branch, it's using info from the last fetch.
git clone http://tfsmr:8080/tfs/IEB/MRGIT/_git/...
% git clone http://tfsmr:8080/tfs/IEB/MRGIT/_git/ReachClient
Cloning into 'ReachClient'...
Username for 'http://tfsmr:8080': [email protected]
Password for 'http://[email protected]@tfsmr:8080':
remote:
remote: fTfs
remote: fSSSSSSSs
remote: fSSSSSSSSSS
remote: TSSf fSSSSSSSSSSSS
remote: SSSSSF fSSSSSSST SSSSS
remote: SSfSSSSSsfSSSSSSSt SSSSS
remote: SS tSSSSSSSSSs SSSSS
remote: SS fSSSSSSST SSSSS
remote: SS fSSSSSFSSSSSSf SSSSS
remote: SSSSSST FSSSSSSFt SSSSS
remote: SSSSt FSSSSSSSSSSSS
remote: FSSSSSSSSSS
remote: FSSSSSSs
remote: FSFs (TM)
remote:
remote: Microsoft (R) Visual Studio (R) Team Foundation Server
remote:
Receiving objects: 100% (150854/150854), 766.01 MiB | 56.63 MiB/s, done.
Resolving deltas: 100% (85690/85690), done.
Checking connectivity... done.
Checking out files: 100% (12181/12181), done.
Use --depth
if you do not need the full history, in CI, or on a slow connection.
git clone --depth=99 http://tfsmr:8080/tfs/...
This command does two things, a fetch
and a merge
.
git pull
Which branch am I on?
git branch
What are the remote branches?
git branch -r
What are my local changes?
git status
What's the history?
git log
git log --oneline
git log --oneline --decorate
Pseudo GUI:
git log --graph --stat --decorate
Also, remember there is a web interface.
git help <command>
git <command> -h
Pretty much any scenario involving git has a blog post or a Stack Overflow question.
Unlike other VCSs, checkout
in git is not a network operation. It changes your repo to reflect some node in the commit graph.
git checkout ST1234_supa_feecha
Create a new branch and check it out:
git checkout -b TS1234_feecha_part1
Always work from a branch. Never commit to master
.
Note: detached head.
Checkout will also copy the contents of a file or files as of some point in the commit graph, to your working directory.
git checkout origin/<branchname> -- path/to/file
git checkout <some SHA> -- path/to/file
git checkout -- path/to/file
Start with a two letter type, followed by a work item number.
STnnnnn
StoryTSnnnnn
TaskBGnnnnn
Bug
Note: can also use underscores and friendlier test to distinguish your branch from the 1600+ branches on MRGIT right now.
Edit stuff. Add as you go.
git add <path/or/glob>
git add -A
If you continue to modify a file you added, you'll need to add it again to include the changes.
Commit stuff you added, bring up editor:
git commit
Add modified files, bring up editor:
git commit -a
Commit with message (don't bring up editor):
git commit -m
Must:
- Include
#nnn
for related work items, wherennn
is the item number. - Subject line 80 characters max.
Should:
- More datailed description, starting after a blank line
Note: I usually put the work item at the end of the first line because the hash character in the first column is treated as a comment by git when using an editor for commit messages.
- Do not commit to
master
, issue a pull request from your branch ontomaster
.
Update master
and the remote tracking branches.
git checkout master
git pull origin master
git pull
Update your branch with changes from master
.
git checkout <branchname>
git merge master
Update your branch with changes from another branch.
git checkout <story branch name>
git merge <task branch name>
Or use the web interface...
git branch -d <branchname>
git branch -D <branchname>
Don't panic.
Undo uncommitted changes:
git reset --hard
Or
git checkout -- some/path/
Redo last commit:
git commit --amend
Undo last commit:
git reset --hard head^
Completely reset a branch to the way it exists on MRGIT:
git reset --hard origin/master
git reset --hard origin/branchname
git checkout <branchname>
These do the same thing:
git push origin <branchname>:<dest branchname>
git push origin <branchname>
git push
Issue a pull request. Get it reviewed.
http://tfsmr:8080/tfs/IEB/MRGIT/_git/ReachClient/pullrequests
- click "New Pull Request"
- Select your branch in "Review changes in" field
- Select destination branch in "relative to" field. i.e.
master
or story branch.
You can also do this after a the pull request.
git push origin :<branchname>
- tv3.slack.com #git-help
- onenote
- How to undo almost anything in git
Note: I used these sites in compiling this presentation, because they came up in a web search of particular topics-- not neccessarily because they're canonical or generally usefull YMMV.