Deutsch English
Your feedback:
Did you like this page? vote3 Yes
vote2 Partly
vote1 No
Your comment?

Add your email address, if you want to get a response

Your name, if you like

Do not change this:
Feedback
Search

Revision / Version Control

This page is about revision control.
05-06-2006 16.46

Subversion (svn)

Subversion is one of the interesting services at all if you want to modify your files ob different machines without the need to synchronise your work manually.
Here is the Subversion manual (Quickstart)
mkdir -p /usr/local/var/my_svn/
svnadmin create /usr/local/var/my_svn/
mkdir -p ~/foo/; cd ~/foo/
svn co file:///usr/local/var/my_svn/
svn add ...
svn diff -r HEAD
svn diff -r 3:5
svn diff -r {2004-11-28\ 15:30}
svn update
svn commit
Mark the file FOO as binary
svn propset svn:mime-type 'application/octet-stream' FOO
svn proplist -v FOO
Set diff otions to svn diff (e.g. to ignore empty lines)
svn diff --diff-cmd diff -x -iEbBu
In order to set the option permanently just set in ~/.subversion/config a small shell-script as your diff command.
Copy the current version from trunk e.g. to develop experimental functions
# svn copy trunk branch/beta1
# svn ci branch/beta1
Committed revision 123.
Merge your changes back to the trunk
# cd trunk/
# svn log --stop-on-copy ../branch/beta1
# svn diff -r 123:HEAD ../branch/beta1
# svn merge -r 123:HEAD ../branch/beta1

This is an Apache2 configuration which will make repositories at /usr/local/var/repositories/svn/NAME accessible via the URL http://HOSTNAME/repositories/svn/NAME:
<Location                     /repositories/svn/>
DAV svn
SVNParentPath /usr/local/var/repositories/svn/
AuthType Basic
AuthName "My Subversion Repository"
AuthUserFile /usr/local/var/repositories/svn/user_passwd
Satisfy Any
Require valid-user
AuthzSVNAccessFile /usr/local/var/repositories/svn/user_authorisation
</Location>
Control the permissions of the different users:
user_authorisation
## Default is NO
[/]
* =

[REPOS1:/]
usera = rw
userb = r

[REPOS1:/trunk/test]
userb = rw

Set line feed format for a file
Property:
svn:eol-style LF
svn:eol-style CRLF
svn:eol-style native

Exclude files
Property:
svn:ignore *

Tell Winmerge to exclude all the .svn folders

Winmerge -> Tools -> Filters -> FileFilters -> New -> For all Users -> Install

Download this file and select it in this dialog
WinmergeSVNFilter.txt
From now on the .svn folders will be ignored.
08-08-2010 14.52

git

Links



Basic usage

  • this site is heavily inspired by a tutorial introduction to git
  • git-gui and gitk --all are very helpful to understand what is happening
  • See the paragraph SPECIFYING REVISIONS in git-rev-parse(1) for possibilities to address a revision in git

Start a new repository

Introduce yourself to git
git-config --global user.name "Mr Foo"
git-config --global user.email "foo@example.com"

Either create a new, empty folder ...
mkdir project
cd project
git-init # git-init-db
... or use an existing one
tar xzf project.tar.gz
cd project
git-init # git init-db

Note: gitk won't work in new git repositories before your first commit. Until then the following error will occur:
Error in startup script: child process exited abnormally
while executing
"close $refd"
(procedure "readrefs" line 47)
invoked from within
"readrefs"
(file "/usr/bin/gitk" line 6370)

Add all files to the repository and commit.
git-add .
git-add--interactive
git-commit

Adopt changes to local repository

What has changed?
git-diff
git-diff path/to/file

In contrast to Subversion you have to tell git which before each commit which of the tracked files should be considered. This is also achieved via git-add
git-add path/to/file
You can also add them via git-gui in a more convenient way.

After you added those files with git-add they are no longer shown by git-diff. But you can still see what changes will be committed
git-diff --cached
git-diff --cached path/to/file

Now really add changes to your local repository
git-commit path/to/new/file
git-commit -m "* Bla bla" path/to/new/file

Another way is to tell git to commit all tracked and changed files without calling git-add on each file
git-commit -a

If you made a mistake in the last commit you can still change it
git-commit --amend
Another way
git-reset --soft HEAD^
...
git-commit -c ORIG_HEAD


Show modifications
git-diff

git-diff --color --color-words
git-diff --ignore-space-at-eol --ignore-space-change
git-diff -- path/to/file

git-diff HEAD -- path/to/file
git-diff HEAD^ -- path/to/file
git-diff HEAD^^ -- path/to/file
git-diff HEAD^^ HEAD^ -- path/to/file

git-diff 68fcc0 ef6274 -- path/to/file
git-diff HEAD ef6274 -- path/to/file
git-diff ef6274 ef6274^ -- path/to/file
git-diff master experimental -- path/to/file
git-diff master origin/master -- path/to/file

git-whatchanged 68fcc0 ef6274 -- path/to/file

git-diff --name-only 68fcc0 ef6274

git-status

git-log

You can also filter the output of diff, e.g. to show only deleted files, only modified files, ...
git diff --diff-filter=D --name-only
git diff --diff-filter=M --name-only

Remove files from the work area and the repository
rm path/to/file # git-rm path/to/file

Remove files only from the repository
git-rm --cached foo

Show who changed what in a file
git-gui blame foo/bar/file.cpp

Exclude files from the repository

There are two possibilities to exclude files from the repository
  • You can exclude them via .git/info/exclude. However this will only affect your local repository.
    # (1)
    foo.txt
    # (2)
    *.html
    # (3)
    !foo.html
    # (4)
    *.[oa]
  • You can create files named .gitignore in any of your folders to exclude files. This will affect files this folder and all of its subfolders. This has the advantage that the .gitignores can be added to the repository and shared among different repositories. If you like to exclude all files of a folder with this method don't forget to exclude the .gitignore from the exclusion.
    *
    !.gitignore
Additional information can be found in gitignore(5).


Patches

Save changes of repository in files in the given folder. These patches can be easily send via mail to propagate changes
git-format-patch --numbered --thread -o /tmp/mypatches/ HEAD^^ HEAD
git-format-patch --numbered --thread -o /tmp/mypatches/ -2

Save to diff between current branch and the branch origin into a patch
git-format-patch                     -o /tmp/mypatches/ origin

Get all patches which are in the given mbox and apply them to the current branch
git-am mymbox
git-format-patch -k --stdout HEAD^^ HEAD | git-am --3way --keep

Send patches directly via mail (if you skip recipient or sender it will be extracted from the repository automatically)
git-send-email --from foo@example.com --envelope-sender foo@example.com --to bar@example.com  /tmp/mypatches/

Apply a patch
git-apply --check   foo.patch
git-apply foo.patch
git-apply --reject foo.patch
git-apply --reverse foo.patch

Apply a given commit to the current branch
git-cherry-pick f6a2c

Maintenance

Speed up repository with compression (do this from time to time)
git-gc

Check repository for bugs
git-fsck

Get other versions of a file in the repository

View other versions of a given file
git-show abcde:path/to/file
git-show HEAD:path/to/file
git-show HEAD^:path/to/file
git-show HEAD^^:path/to/file
git-show HEAD~3:path/to/file
Restore older versions of a given file
git-checkout HEAD^ path/to/file

Tags

Ein Tag setzten
git-tag v1.0

Branches

Create branch
git-branch experimental; git-checkout experimental
git-checkout -b experimental

Show all branches
git-branch
git-branch -r
git-branch -a

Which branch is current
ls -l .git/HEAD

Switch branch
git-checkout experimental

Switch back
git-checkout master

Undo all local modifications
git-checkout -f

Merge all changes from branch experimental into the current branch
git-pull . experimental

Delete branch
git-branch -D experimental

Merge two branch back together
The current branch will get the changes of the branch experimental so both will be equal
git-merge experimental
Merge a conflict during merging
git-add path/to/new/file
git-commit

rebase
Assume you have the following branches
     -->A-->B-->C foo
/
D-->E-->F-->G master

and you want that the foo branch
A-->B-->C

starts at the head of the master branch
             -->A-->B-->C foo
/
D-->E-->F-->G master

If you are already in the foo branch it's enough to issue
git-rebase master
to move the current branch on the head of the master branch.

Otherwise the following command
git-rebase master foo
moves regardless of the current branch the foo branch on top of the head of the master branch.

Finally you can even move a given sub branch onto the head of a another branch. Assume you have
              F-->G-->H bar
/
C-->D-->E foo
/
A-->B master

the the following command
git-rebase --onto master foo bar

will achieve this result

     C-->D-->E  foo
/
A-->B master
\
F-->G-->H bar

Branch strategies

Teamwork

Suppose Alice has a git repository in /home/alice/project, now Bob wants to help Alice and also work on the project. With the following command he'll gets a clone of the repository in the folder myrepo.
git-clone /home/alice/project myrepo

After you cloned the remote repository you'll find one branch, master
git branch
* master

However, the remote repository might have more than one branch. Luckily, there are already here for you
git branch -r
git branch -a

If you want to have a first look into one of those branches, you can switch to them right away
git checkout origin/SuperBranchNr1

If you like to use this remote branch also in your repository, create a local branch for it and mark it to track changes
git branch --track SuperBranchNr1 origin/SuperBranchNr1

If Alice commits new changes into her repository Bod can pull those changes into his repository
git-pull

If it Bob who did commits into his repository, he can either push those changes into Alice's repository, or she can pull them by herself.
git-pull /home/bob/myrepo

If Bob created new branches he can push the like this into Alice's repository
git push --all origin

He can also push the single new branch MyNewBranch to the remote repository origin
git-push origin MyNewBranch

You can also fetch the changes first without an immediate merge
git-fetch /home/bob/myrepo

It is even possible to add references to more than one repository. Add a new one like this
git remote add origin git@foo/bar
git remote add origin2 git://foo/bar
git remote add origin3 ssh://user@foo.bar/~/foobar.git

Show remote repositories
git remote show
git remote show origin

Remove remote repository
git remote rm origin2

Your own git server

There are several possible protocols available
  • git-deamon
    Fast, but read only
  • http
    Slow, but no problems with firewalls / proxies. Normally also only read only.
  • ssh
    Read and write access
  • Local filesystem
    Fast, read and write access
See also HOWTO setup a git repository.

Example for git deamon server
Server, with a given folder where the repository should lie, e.g. /var/cache/git
git-daemon --verbose --base-path=/var/cache/git

Client, we already have a repository (e.g. /home/foo/bar) and like to export it to the server
git-clone --bare /home/foo/bar MyFirstRepository.git
Enable export on repository
touch MyFirstRepository.git/git-daemon-export-ok
Copy folder to server
scp -r MyFirstRepository.git myserver.example.com:/var/cache/git/
Now you should be able to access the repository via git
git-clone git://myserver.example.com/MyFirstRepository.git

Example for git ssh server
We also clone a repository (or use an existing one)
git-clone --bare /home/foo/bar MyFirstRepository.git
We create a new user, e.g. git which will be used to log in via ssh (or use existing users).
If you use an extra user, you might consider to restrict his shell to /usr/bin/git-shell (/etc/passwd)
You might use a different port for the ssh deamon for the git usage
git clone ssh://git@foo.bar:9418/~/foo.git

Subversion and git

One time import from a subversion repository into a git repository
git-svnimport http://example.com/mysvnrepository
This will expect that you followed the subversion recommendation to have the following repository structure
trunk/
branches/foo
branches/bar
branches/...
but with appropriate command line parameters you can import other structures as well

In one of my projects there was no trunk folder at all. As of now (August 2007) git-svnimport can not import such repositories. However there is a small patch for git-svnimport and empty trunk folder. In my project with commit 325 a trunk folder was created and everything was moved into it. With a git-importsvn version which can handle empty trunk folders the import worked in two steps
git-svnimport         -s   1 -T ''      -l 324 http://example.com/myproject
git-svnimport -o tmp1 -s 325 -T 'trunk' http://example.com/myproject
git-checkout tmp1
git-rebase master
However there was manual intervention required to merge both parts.

If you like to use git and subversion in parallel you might be interested in git-svn
git-svn init

git undo

If something went wrong with your git repository you can try to undo the last git actions
# git reflog
24f34f2... HEAD@{0}: pull : Fast forward
68fh47g... HEAD@{1}: checkout: moving to master
90cdrt3... HEAD@{2}: pull : Fast forward
62dgs35... HEAD@{3}: rebase: ...

# git reset --hard HEAD@{1}

Find erros with bisec

If the current project has a bug delcare it as bad and explain which is the last version which worked
git-bisect start
git-bisect bad
git-bisect good v2.6.13-rc2

This will give you a version between the broken and the working version. Try it and declare it as bad or good.
git-bisect good
until you find the modification which causes it. To quit bisec and get back the latest version
git-bisect reset

Kernel

Get a copy of the (complete!) kernel repository from Linus
git-clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git linux-2.6
Note that there will be no tags for the stable kernel in it. So you may decide to use the stable Kernel git instead
git-clone git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-2.6.16.y.git
which has tags for the stable kernel.

List all available tags
ls .git/refs/tags/

If you already have downloaded the Linus git you can use it as a source for the stable one (untested, needs git 1.3)
git-clone --reference oldfolder git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-2.6.16.y.git newfolder

Show difference between two versions for the file MAKEFILE
git-diff v2.6.17-rc4..HEAD Makefile

Create a new branch, and get version with a specific tag into it (does not require network as you have complete repository).
With this command you can get a specific kernel out of the git
git-checkout -f master
git-pull
git-checkout -f -b my-new-branch tags/v2.6.16.19

03-08-2010 18.43
Powered by PHP Created with Xemacs Valid XHTML 1.0! Valid CSS!