Workspace and Repositories
What you see and edit in your workspace directory is called your working copy.
Changes can be saved to your local repository with the two subsequently called commands git add and git commit.
To send changes from your local repository to the remote repository git push is used.
Changes from the remote repository are fetched and stored in the local repository through git fetch.
To specify a version to be used in the workspace - meaning files of the specified version are put into the file system - git checkout is used. The specified versioned state is checked out from the local repository to the workspace.
Fetch and Pull
A fetch updates the local information about the remote repository - you fetch the remote information.
After a fetch, when new commits are available, the commits can be integrated into the local branch and working copy through a merge or rebase.
A pull is a shorthand which does a fetch first, and then tries to merge or rebase (depending on the passed parameter or configuration) the changes of the corresponding remote branch into the current branch. Index
The index is a save-state before you commit them, at which point they become history.
Working copy — git add --> index — git commit --> local respository
GUIs like EGui often allow you to skip this step, essentially commiting from the working copy directly.
To remove entries in the index use:
git reset (-–mixed)
Where --mixed is the default option.
To remove entries in the index and the corresponding changes in your working copy use:
git reset --hard
HEAD, index and working copy
HEAD points to the commit you checked out. (It is a history pointer.) When you are working on a branch it points to the branch.
Working copy ---git add--> index ---git commit--> HEAD
In TortoiseGit the index is often negated. In the commit dialog the selected files are committed from the working copy to HEAD directly. EGit has a Git Staging view that can display it.
Reset vs Checkout vs Revert
If you want to revert changes (in SVN terms revert) in git you will want to do a git checkout.
To revert working copy changes to the file pom.xml (use the staged version):
git checkout pom.xml
To revert working copy and staged changes:
git checkout HEAD pom.xml
To revert parts of a file (to the staged state):
git checkout --patch pom.xml
A git revert is not for reverting working copy or staged changes, but to revert committed changes through a new commit (in subversion terms a reverse merge).
git reset <path> is used to unstage changes.
Otherwise, a git reset (without a path as param) is used to reset the current branch head to the specified commit or HEAD. There are 3 reset types: Soft, mixed and hard.
Soft only resets your HEAD - the commit your staged and unstaged changes are based on (the branch and commit you checked out).
Mixed will reset HEAD and index; dropping any changes you may have added to the index.
Hard will drop any changes you made in your working copy. Make sure you do not have uncommitted changes you want to keep when doing this!
Rebase vs Merge
A merge merges two branches in a commit. In the example diagram above the commits in the branches master and feature1 are based on commit 4.
When merging branch feature1 into master a new commit (a merge commit) is created in branch master, which combines the two last branches commits - combines the two history lines into one. This is the preferred action to insert to add a finished feature into the main branch.
When rebasing feature1 on master each commit in branch feature1 are reapplied on top of master. As they are reapplied on top of a different commit the commit hash and thus the commit differs from the original - we rewrote history. The advantage however is that we kept a linear line of history.
A rebase re-commits the commits you made on top of a common ancestor. As we have a server repository we want to use as a base-line, and which we push changes to, rebasing should be preferred over merging when possible, in simple and local cases. For feature branches with several commits in a parallel line of history, especially after having been pushed to a remote repository - a merge commit is often preferred to preserve history.
Interactive, Visualized Example
For an interactive visualisation:
Entering the following commandos, what do you expect the merge and rebase to change on the right side?
git branch a git branch b git branch c git checkout a git commit git checkout b git commit git merge a git checkout c git commit git checkout b git rebase c