Categories
Git How to Reference

Notes on a Successful Git Branching Model

This refers to the explanation on the web site A Successful Git Branching Model. It was only after reading this article that Git really started to make sense to me. It’s an application of Git, and it seems that Git only makes sense within this context.

  • In this branching model, there are only two branches that live forever.
    • master
    • develop
  • origin/master
    • Where the source code of HEAD always reflects a production-ready state.
  • origin/develop
    • Where the source code of HEAD always reflects a state with the latest delivered development changes for the next release.
    • This branch is also known as the Integration branch.
    • This is where automatic nightly builds are built from.
  • When the source code in develop reaches a stable point and is ready to be released, all of the changes are merged back into master, and then tagged with a release number.
    • By definition, each time changes are merged into master, it’s a new production release.
Categories
Git Reference

Notes from Git for Ages Four and Up

Here are my notes from watching the video Git for Ages Four and Up. It contains a really good expanation of how Git works under the hood. The speaker (Michael G. Schwern <schwern@pobox.com>) created a new repository, and then created a new file, added some text to it, saved it, closed it, then added it to the Staging Area, and then committed it.

git add

  • Adds a file your working directory, to the staging area (the Index), as a BLOB.

git commit

  • Creates a “Commit” object from that BLOB.
    • That somehow points to the files that are stored in Git.
      • The commit contains all of the files in the repot – not just the ones that were just staged.
  • And attaches two labels (“References”) to it.
    • HEAD
      • The name of the most recent Commit.
      • Always points to the tip of the branch that you currently have checked-out.
    • MASTER
      • The name of the currently checked-out Branch.
      • The one that advances upon “git commit”.

When you create a branch

  • All Git does is attach a new branch label to the Commit currently pointed to by HEAD.

When you perform a “git checkout”

  • Git merely switches which branch it’s going to advance when you perform a “git commit”.
    • We say the branch becomes active.
  • And it moves HEAD to the commit object that has that branch label.
  • Git populates your Working Directory with a snapshot of the branches tip commit..

Commit ID

  • Content + Author + Date + Log + Previous Commit ID.
  • A hexadecimal UUID (Universally Unique Identifier).
  • Is a checksum (Hash)
  • Git calculates this value by running the bits in the BLOB through a function, which produces a thirty eight digit hexadecimal value.

Staging Area (Index)

  • Allows you to build up a commit.
  • You can add multiple files to the index, and then commit them (i.e., all files as one commit object).

The basic Git workflow

  • You isolate your work from everyone else’s (spawn a new branch to work in).
  • Do some work (modify one or more files).
  • Update from everyone else (pull from origin).
  • Commit your work to your local enlistment (commit).
  • Finally, you share your work with everyone else (push to origin).

Merge

  • git checkout your local master (feature/api_doc).
    • You’ll be bringing your work back into this branch.
  • Git performed a Fast Forward.
    • Since no merging of content (all modifications added new content).
      • A merge object wasn’t created.
    • All Git did was move the branch label to the commit from the ‘from’ branch.
    • Git also moved the HEAD label, because you have that branch checked out.

git reset –hard HEAD^

  • This undoes the last commit.
  • But all it does is move reference labels!
  • Moves the current branch label (Master), back one commit to HEAD-1.
  • –hard does a checkout, so that you end up where you want to be.

git log –graph –decorate –all

git commit does not mean share (inflict).

  • Commit is a local operation.

Merge

  • Git can merge in many different ways.
  • It picks the most convenient way.
  • Fast Forward is the simplest.

Working with others

  • This is where remote repositories comes in.
    • remote commands.
      • Push, Fetch, and Pull.

Clone

  • You normally start working on a clone of an existing repository.
  • When you clone a repository, git attaches labels to the objects in your local repository to mark the tracking branches.
  • origin/MASTER
  • Git clones only origin/MASTER (the default branch).

Directed Acyclic Graph

  • Graph – a collection of nodes and edges.
  • Directed – the edges all point to the previous node.
  • Acyclic – there are no cycles. I.e., the path from one commit to any other is unique.

Pull

  • Is actually a Fetch followed by a Merge.
  • When you’re starting out, it’s often easier to do a pull as two steps (a fetch followed by a merge).

We’re going to create a third repository

  • So we can have someone other than us, doing work.

We’ll create a new branch called “bugfix”

  • And we’ll create a new file in it called “baz”.

git push origin bugfix

  • Sometimes you have a space between “origin” and “bugfix”, and sometimes you have a slash between them.
    • The slash version refers to the label (origin/bugfix) on your repository. This is a reference to a tracking branch.
    • The space version refers to the remote (origin) branch (bugfix).

Push

  • Does two things.
    • Git checks to see if the remote repository has the commit object your pushing.
      • If it doesn’t, then it checks to see if it has the ancestor commit object(s).
      • If it does, then
        • Git sends over the commit object (plus a branch label, if it’s on a new branch).
      • If it doesn’t, then
        • Git send all of the ancestors + the commit object.
  • This is where the cool thing about IDs comes in (this is why git is so amazingly fast).
    • Every ID is unique.
    • Every commit is unique.
    • Commits never change.
    • This means that every commit can be uniquely identified by its ID.
    • Since IDs contain the ID of the previous commit,
      • Every commit’s history can be uniquely identified by its ID.
      • Two devs push to the same repo without pulling…
        • If I have ae123, and you have ae123,
          • Then we know everything from ae123 on down is exactly the same.

Tag

  • Tags are good to use when you continually jump back to a particular snapshot.
  • E.g., git tag v1.0 bfce7
  • All Git does is add a label (reference) to the commit object you want to tag.
  • Excep that tag labels never move.

git reflog

  • This is your rescue command.
  • You can use this command when something gets screwed up, to find a particular commit ID.
  • Git shows you the commits you’ve been working on lately.

You can combine git add and git commit into one step

E.g., git commit -a foo.

Rebase

  • This is a local operation.
  • Example use: instead of fixing a typo and then committing the file again, you can perform a rebase instead.
  • Git rebase doesn’t rewrite history. It writes new history (you can’t actually change history in Git).
    • Instead, git creates a whole new line of history.
  • Interactive rebase.
    • Go back two commits.
      • git rebase -i HEAD^^
      • Git says “I’m going to replay these things as if they were patches, one on top of the other.
        • Nothing happened! (because nothing changed).
      • You can “squash” a later commit into a previous commit (so the typo fix you made is written on top of the version with the typo).
        • I.e., you combine two (in this case) commits into a new commit.
        • The original two commits become detached!

Note: Once you have pushed, don’t rebase or you’ll screw up everyone else’s history! So never rebase until after you’ve pulled!

Categories
Git How to

How can you see the Differences in a File, Between Two Commits?

In Eclipse, right-click the file in Git repository explorer (in the working tree), and then select “Show in > History”. Then, select the two commits in the History pane (hold Ctrl when selecting commit items), and then right-click and select “Compare with each other.

Categories
Git Reference

Pro Git Commands

Command Description
git add [file]
  • adds [file] to the index (stages the file).
git add -i
  • runs the interactive staging script.
git branch
  • lists branches.
git branch -a
  • lists all branches (both local and remote).
git branch [branch]
  • creates a new branch.
git branch -d [branch]
  • deletes a branch.
git branch –contains
  • shows which branches contained the named commit (HEAD if not specified).
git branch –merged
  • shows which branches are already merged into the branch you’re currently on.
git branch –no-merged
  • shows all of the branches that contain work that you haven’t yet merged in.
git branch –set-upstream-to origin/[branch]
  • sets this branch to track a remote branch. Remote branch must exist first.
git branch -v
  • shows the last commit on each branch.
git branch -vv
  • shows the tracking branches you have setup.
git cat-file -p HEAD
  • shows details (files) about the HEAD snapshot.
git checkout – <file>
  • unmodifies a modified file. Discards your changes. Reverts your file back to last commit.
git checkout [branch]
  • switches to another branch.
git checkout -b [branch]
  • creates and checks out a new branch.
git checkout -b [branch] [remote]/[branch]
  • creates and checks out a new branch, and also sets up a remote tracking branch.
git checkout –track [remote]/[branch]
  • creates and checks out a new branch, and also sets up a remote tracking branch.
git checkout –track origin/[branch]
  • creates a local tracking branch from a remote branch.
git clone <URL>-
  • clones a repository.
git commit –amend
  • adds more files to the last commit (that you still haven’t pushed).
git commit -m ‘message text’
  • commits staged files.
git config –list
  • lists your Git configuration.
git diff
  • shows changes in the working tree that are not yet staged.
git diff HEAD
  • shows changes in the working tree since your last commit.
git diff –cached
  • shows changes between the index and your last commit.
git diff –check
  • identifies possible white space errors, and lists them.
git diff –staged
  • same as git diff –cached.
git fetch [remote]
  • downloads all of the changes on the server that you don’t yet have.
git fetch –all
  • fetches all remotes.
git grep -n [search term]
  • finds the files that contain the search term. The -n switch prints the line numbers of matches.
git grep –count [search term]
  • finds the files that contain the search term, and how many times in each file.
git help <verb>
  • shows help on a particular command.
git init
  • creates a new, empty git repository.
git log
  • shows the history of commits, in revere chronological order.
git log –graph
  • shows a graphical representation (in ASCII) of your commit history (showing branches).
git log -p -2
  • generates a patch between the last two commits.
git log –pretty=oneline
  • shows commits one line at a time, pretty.
git log –since=2.weeks
  • shows the commits from the last two weeks.,
git log –stat
  • shows details for each commit.
git log [branch1]..[branch2]
  • shows what’s in branch1 that hasn’t yet been merged into branch2.
git log [remote]/[branch]..
  • shows the commits in your current branch, that aren’t in [origin]/[branch].
git log refA refB ^refC
  • shows all commits that are reachable from refA or refB, but not refC.
git log [branch1]…[branch2]
  • shows the commits that are not common to both branches.
git log -S [search term]
  • shows when the search term was introduced.
git log -L :[function name]:[file name]
  • shows the history of a function or line of code.
git ls-files -m
  • show files. In this case (-m) modified files. Also -s for staged files.
git ls-tree -r HEAD
  • lists the files in the HEAD tree, along with each one’s commit ID.
git merge @{upstream}
  • if this is a tracking branch, merges in remote tracking branch.
git merge [branch]
  • merges branch into current branch.
git merge –abort”
  • aborts the current merge.
git mergetool
  • runs a three-way merge (between local, remote, and common ancestor).
git mv <file_from> <file_to>
  • renames a file.
git pull [remote]
  • fetches and merge.
git push [remote] [branch name]
  • pushes to remote branch.
git push [remote] –delete [branch]
  • deletes a remote branch.
git push [remote] [tag name]
  • pushes a particular tag upstream.
git push [remote] –tags
  • pushes all tags.
git push –set-upstream [remote] [branch]
  • pushes the current branch, and creates the same branch on the remote, and tracks it.
git remote show [remote]
  • lists the details about a particular remote.
git remote
  • lists your remotes.
git reset <file>
  • unstages a file (essentially copies <file> from HEAD to index.
git reset [commit]
  • Moves HEAD to point to [commit].
git reset HEAD~
  • Removes the last commit. But also unstages files in the Index.
git reset –hard HEAD~
  • Removes the last commit. Cleans the index and working tree (nothing changed, nothing staged). Note: This is the dangerous version of the reset command – because you’ll lose your work in progress.
git reset –mixed HEAD~
  • Same as git reset HEAD~.
git reset –soft HEAD~
  • Undoes the last commit, without changing the working tree or the index.
git rev-parse branch
  • shows the commit that a particular branch points to.
git rm <file>
  • removes a file from the working tree and the index.
git show
  • shows details of the last commit.
git show HEAD@{n}
  • shows the commit that HEAD pointed to “n” commits ago.
git show [branch]@{yesterday}
  • shows the commit on a particular branch that HEAD pointed to yesterday.
git show HEAD@{2.months.ago}
  • shows the commit that HEAD pointed to two months ago.
git show HEAD^
  • shows the parent of HEAD.
git show d921970^2
  • shows the second parent of the specified commit. This only works for merge commits.
git show HEAD~n
  • shows the nth first parent. Equivalent to HEAD^^^ (for n = 3).
git stash
  • saves your staged and modified files on the stack.
git stash list
  • lists your stashes.
git stash apply
  • applies the last stash on your current index and working directory.
git stash apply index
  • also restages any files that are staged, but updates them with the stash.
git stash drop stash@{n}
  • deletes the specified stash.
git stash pop
  • applies a stash, and then deletes it from the stack.
git status
  • shows the status of your working tree.
git status -s
  • the short version of git status.
git tag v1.4
  • tags HEAD as v1.4.
git tag
  • lists all of the tags.
Categories
Git Reference

Common Git Commands

Command Description
add Add file contents to the index
bisect Find by binary search the change that introduced a bug
branch List, create, or delete branches
checkout Checkout a branch or paths to the working tree
clone Clone a repository into a new directory
commit Record changes to the repository
diff Show changes between commits, commit and working tree, etc
fetch Download objects and refs from another repository
grep Print lines matching a pattern
init Create an empty git repository or reinitialize an existing one
log Show commit logs
merge Join two or more development histories together
mv Move or rename a file, a directory, or a symlink
pull Fetch from and merge with another repository or a local branch
push Update remote refs along with associated objects
rebase Forward-port local commits to the updated upstream head
reset Reset current HEAD to the specified state
rm Remove files from the working tree and from the index
show Show various types of objects
status Show the working tree status
tag Create, list, delete or verify a tag object signed with GPG

You can exit a listing by pressing Ctrl+c.

Categories
Git How to

How to Remove Content From the Doc Build

I documented a new feature a month ago, and it’s now live. But now 3rdParty wants me to pull it – because the commercial launch has been delayed.

Since you use a Git branching model to separate your work-in-progress from your published work, and then once you’ve completed the new work, you then merge it into the published doc set, you should be able to solve this issue using Git.

You can remove the content by reversing the commit that represents it. When it’s time to put the content back, you do it by reverting the revert commit. You might think it makes sense to merge the content back in, as you originally did, but Git has captured that “action” as a commit object already (as a dimension, the concept of time takes on properties and behaviors in Git world!).

Here’s my research source: http://git-scm.com/blog/2010/03/02/undoing-merges.html

Notes

In Eclipse > Git Reflog (Java (Writing) perspective).

Looking at the entries in the Reflog Message column, you can easily see where new content was merged into your local main line branch. They’re the “Merge Commits” – the ones with the “merge” icon.

Can you filter-out all of the other commit types? Yes! Simpy type “merge” into the Filter field, and press Enter.

Categories
Git How to

How to Find Out Which Files are Tracked

git ls-files
Categories
Git How to

How to Undo a Commit

git reset HEAD~1
Categories
Git How to

How to Recover a File that was Deleted by a Commit

I’m still not sure how this happened. It could have resulted from switching back and forth between the MobileUserDocs branch and the 2WaySMS branch. You altered your .gitignore to have it ignore

  1. Find the commit that deleted the file.
git rev-list -n 1 HEAD -- <file_path/>

E.g.,

git rev-list -n 1 HEAD -- doc/user/v1/source/mobile-content/topics/procedures.dita
  1. Checkout the file.
git checkout a39f1d72964dfc6240a7c1d9678a4add9b8bdb7d^ -- doc/user/v1/source/mobile-content/topics/procedures.dita

Or in one command

If $file is the file in question.

git checkout $(git rev-list -n 1 HEAD -- "$file")^ -- "$file"

Note: You must include the quotes.

E.g.,

File Name: “doc/user/v1/source/mobile-content/topics/concepts.dita”

git checkout $(git rev-list -n 1 HEAD -- "doc/user/v1/source/mobile-content/topics/concepts.dita")^ -- "doc/user/v1/source/mobile-content/topics/concepts.dita"
Categories
Git How to

How to Create a Copy of One of the Remote Branches Locally

Just check it out, using its local name.

E.g.,

git checkout release/current