My git workflow explained

During the past couple of months I’ve kept a log of all my git usage. Trying to get a list of all the typical stuff one needs to do. This post list these with git commands and some explanation of the process. I won’t explain all options, since git someCommand --help will show you all there is to know.

On to the list:

Standard change workflow
This workflow allows you to commit locally without thinking about writing commit-messages that are useful to anyone else but yourself. All local commits will be compressed into one commit when you are ready to commit to the remote repository.

This workflow uses git svn, because that’s was what I used at the time.
If you’re not using “git svn” then replace the following:

  • “git svn clone” with “git clone”
  • “git svn rebase” with “git pull”
  • “git svn dcommit” with “git push”

Here is the code:

# Clone a SVN repository
git svn clone URL
# Create a work branch
git checkout -B work

# Do some work … and then

# Add the updated files to git
git add -i
# Commit the changes locally
git commit -m ‘local comment’

# Do some more work and commit them
git add -i
git commit -m ‘another local comment’

# Return to the master branch (the one tracking SVN)
git checkout master

# Fetch all changes from SVN
git svn rebase

# Apply all changes on the work branch to master – in one update (with no commit)
git merge work –squash

# Commit to master – with a good comment
git commit -m ‘Some comment that is useful on the remote server’

# Push to SVN
git svn dcommit

# Create a new work-branch, ready for new things.
git checkout -B work

Procedure explained:

Clone a repository. Create a branch “work” to work on. Add files and commit them. Do some more work. Move to the master branch and refresh it from remote (“git svn rebase” or “git pull”). Merge the changes made on the work-branch to master into one change, do not commit the changes. Commit the changes with a useful comment. Push the changes to the remote server. Reset your work-branch to the point just committed to remote, and return to it.

Integrate p4Merge (available for Windows, Mac OSx, Linux)
P4Merge is free to use and is IMHO the best merge-tool available. It’s supported by git, which makes it very easy to integrate.
Add this to your git global config ( git config --global -e ). Substitute the path with the place where you installed p4merge.

[merge]
tool = p4merge
[mergetool “p4merge”]
path = C:\\Program Files\\Perforce\\p4merge.exe
[diff]
tool = p4merge

Some usefull aliases
While we’re on the subject of global config stuff. Here are some aliases I use every day:

Add them to your global config ( git config --global -e )

[alias]
squash = merge –squash
b = branch -v -v
r = remote -v -v
s = “status ”
last = log -1 HEAD
l = log –pretty=format:\”%h | %an | %ai | %s %d\” –color –graph
la = log –pretty=format:\”%h | %an | %ai | %s %d\” –color –graph –all
co = checkout

Commit a few files to remote repository while working on a huge update.

You need to add some changes you’ve made on your workbranch to the remote repository. But your work is not done, so you can’t commit everything.

I’m using git add -i here. Use that or just git add [filenames]. I like the interactive mode, but it’s not for everyone.

git add -i
git commit
git add -i # Add non-versioned files, that should be versioned. This will included them in the stash
git stash
git checkout master
git pull
git merge work
git push
git checkout work
git rebase master

Procedure explained:
Add the files you need to push to a commit on your work-branch. Commit the files. Stash the rest of your updates. Jump to your remote-connected branch. Update the branch from remote. Merge your work – this should result in a fast forward. Push changes to the remote. Return to your work branch and rebase it.

Rebase is would be needed if you made further changes while on the master-branch and need those changes available on the work-branch.

Another way to get the changes would be to use git cherry-pick instead of merge.

Revert a specific file
Fairly simple stuff – but people tend to forget it.

git checkout — filename

Reset git
Reset current HEAD to the specified state. When you need to return to a known state and drop all changes.

git reset –hard master

where “master” could be any tree-reference. A branch (master, work, …). A commit-hash, …

Remove all non-versioned files

git clean -f

-f is needed otherwise git won’t delete non-versioned files.

Ignore a checked in file
Stop tracking this file – whatever it’s status.

git update-index –assume-unchanged

Remove a file from git, after it is deleted in the file-system

git rm filename

This will remove the file from local filesystem and from git.
If you need to keep the file in the local filesystem use

git rm –cached filename

What files was commited in a given commit

git diff-tree –no-commit-id –name-only -r a-commit-hash

Options explained:
“–no-commit-id”, will uppress id output
“–name-only”, will suppress listing of differences
“-r”, will show all levels, not just the first one.

Where did my stuff go??
Sometimes you’ll need to get a list of all commits – no matter how confusing it is. For example you know that a file, recently deleted is still present on a commit somewhere. You remember the commit message, but need the hash, so you can retrieve the file.

git reflog

or

git log –walk-reflogs [branch]

These will list all commit messages.

List all files that ever existed

git log [branch] –pretty=format: –name-status | cut -f2- | sort -u

List files under version control

git ls-tree -r master –name-only

This will list all files git knows or ever knew about.

This entry was posted in Git and tagged . Bookmark the permalink.

Leave a Reply