====== Gui ====== * ggit: qt one, very good * gitk: tk but very usefull * kompare: to merge files and directory ====== GIT-SVN ====== * checkout a repository from svn (specify the revision you want). In general HEAD is what you want. This command create two branch: - git-svn wich is a remove branch (a branch that cant be modified and never checked out) - master that track git-svn git svn clone -r HEAD file:///home/ctaf/svntest/repos/test test-gitsvn You can then work in master, if you would like to use it the svn way (only one local branch) * fetch the svn repository into our git tree with all revision(checkout/update). The clone command already do this. If you used init in place of clone, then fetch -r HEAD is what you want. You dont want to download each modification, only the tree in the state of the last revision (head) This command is used #dont call this after init, or your checkout will take hour... git svn fetch #call this after init to only download the delta of the last change git svn fetch -r HEAD #fetch a specific revision git svn fetch -r 123 create a new git branches to work on this will move the change not commited you made to the new branch git-checkout -b foo commit change in the local git branch #-a to include all modifications git-commit -a commit to the svn (the delta change) git-svn dcommit how to update a branch with local change: stash allow to store local modification and restore them with stash apply when we want git stash git-svn rebase --all git stash apply ====== SVN vs GIT ====== with git you cant modify the svn branch (named git-svn), it is a remote branch. But by default you have a branch named master that track git-svn (allow to get update from it using git fetch). #checkout svn checkout http://grk.svn.sf.net/svnroot/grk mygrk git clone -r HEAD http://grk.svn.sf.net/svnroot/grk mygrk #update svn up ##solution 1: to rebase your change to the current svn git svn rebase ##solution 2:to fetch only the remote branch (git-svn), then (rebase or merge) git svn fetch git rebase git-svn git merge git-svn #commit to our local branch (-a to include modified file in the commit) git commit -a #commit to the svn (-n to see idontremember) git svn dcommit -n ====== Branches ====== * create a new branch tracking the previous one: git checkout -b newbranch * switch between branches: git checkout branch * rebase a branch on another one: git rebase branch PS: rebase and merge are similar, rebase re-apply the change of the branch on the new branch we specify, whereas merge, keep the history of the branch, and only merge the new one. A branch rebased "pre-merge" then reapply change. Rebase allow to maintain a little fork of a foreign branch. * merge a branch with another one: git merge branch * remove a commit from a branch: #remove commit HEAD, HEAD^ and HEAD~2 #the --soft prevent the auto commit, you will need to commit the change by yourself git reset --soft HEAD~3 * reset all change you added with git add: #remove all change in the index (this doesnt change files) git reset * revert all modification you made til the last commit #force checkout git checkout -f * remove a remote branch git push : ====== SVN Branches ====== comment gérer les branches svn: # make a tag svn copy /home/svn/trunk /home/svn/branches/mybranch # switch to that tag svn switch /home/svn/branches/mybranch Comment les gerer dans git: # get all tags git svn fetch --fetch-all # see all tags git branch -r trunk tags/mybranch # switch to a svn tags git reset --hard remotes/mybranch # create a new svn tags from git svn cp addr/trunk addr/tags/tagid git svn rebase --all ====== GIT ====== default config #turn color on git config --global color.diff auto git config --global color.status auto git config --global color.branch auto #set your name and mail git config --global user.name "Your Name Comes Here" git config --global user.email you@yourdomain.example.com ====== Git remote branch ====== on the server to create the repository: mkdir /repos/linux.git cd /repos/linux.git git --bare init #switch to a branch on the local git git checkout aldebaran-rt #subscribe the local branch to the remote branch git remote add linux-aldebaran-origin cgestes@sirius:/opt/aldebaran/sys/linux-aldebaran.git #pull # may be origin or git-svn for svn (but git-svn MUST use rebase, not push/pull) git pull linux-aldebaran-origin aldebaran-rt:master #push git push linux-aldebaran-origin aldebaran-rt:master ====== GIT submodule ====== its the same as svn:external ====== GIT subtree ====== allow to merge another repository into ours http://www.kernel.org/pub/software/scm/git/docs/howto/using-merge-subtree.html ====== Git Svn Bare Repo ====== from http://gsocblog.jsharpe.net/archives/12 Git-svn bare mirrors I’ve been trying to automate the updating of my git-svn repos on my server via cron and I’ve finally succeeded in getting something working so I thought I’d share how I’ve got things setup since there seems to be a lack of information about how to do this. First hurdle was git-svn doesn’t understand about bare repositories - it always looks for a .git directory. Fortunately this is easily solved since git-svn does support the $GIT_DIR environment variable. So I simply set this to . and run the git-svn commands from within the repository directory. So I initialise the repository with the appropriate git-svn init command and then call fetch to retrieve the svn history. The next problem is that the refs fetched using git-svn are placed in refs/remotes which isn’t cloned when you do a regular git clone. So we need to plugin to the hooks to update the refs after we update the repository; an example script of how to this is provided below (Taken from dscho.git): #!/bin/sh git for-each-ref –format=”%(refname)” refs/remotes | sed “s/refs\/remotes\///” | while read ref do git update-ref refs/heads/svn/$ref refs/remotes/$ref done git for-each-ref –format=”%(refname)” refs/heads/svn | sed “s/refs\/heads\/svn\///” | while read ref do if ! git-rev-parse refs/remotes/$ref > /dev/null 2>&1 then git update-ref -d refs/heads/svn/$ref refs/heads/svn/$ref fi done I call the script from the post-update script (which you should make executable by running chmod +x hooks/post-update). This script suffices but doesn’t quite do what I’d like; I’d like the tags to be placed in refs/tags/svn rather than refs/heads/svn, but the script linked will do for me for now. My cloned repositories are available at http://git.jsharpe.net/, unfortunately I can’t offer the git protocol since my host doesn’t allow it. As I get time I’ll convert more of the Gnome repositories; I’ve only converted the ones I know I’m going to be working on for the moment. another one : (from http://www.shatow.net/bryan/) #! /bin/sh # post-update script to fix svn branches/tags refs # Point tags to refs/tags/svn/* for ref in $(git for-each-ref --format="%(refname)" refs/remotes | sed -e 's:refs/remotes/::' | grep '^tags/' | sed -e 's:tags/::'); do git update-ref refs/tags/svn/$ref refs/remotes/tags/$ref done # Delete obsolete tags for ref in $(git for-each-ref --format="%(refname)" refs/tags/svn | sed -e 's:refs/tags/svn/::'); do if ! git rev-parse refs/remotes/tags/$ref > /dev/null 2>&1; then git update-ref -d refs/tags/svn/$ref refs/tags/svn/$ref fi done # Point branches to refs/heads/svn/* for ref in $(git for-each-ref --format="%(refname)" refs/remotes | sed -e 's:refs/remotes/::' | grep -v '^tags/'); do git update-ref refs/heads/svn/$ref refs/remotes/$ref done # Delete obsolete branches for ref in $(git for-each-ref --format="%(refname)" refs/heads/svn | sed -e 's:refs/heads/svn/::'); do if ! git rev-parse refs/remotes/$ref > /dev/null 2>&1; then git update-ref -d refs/heads/svn/$ref refs/heads/svn/$ref fi done ===== Hook to remove trailing white space and convert tab to space automatically ===== http://kerneltrap.org/mailarchive/git/2009/2/11/4949394 ===== Git ammend commit ===== you have : D---E---F---G master, to amend revision E do: $ git branch tmp $ git reset E $ git commit --amend $ git rebase tmp master $ git branch -d tmp or git rebase --interactive E^ ====== Git rebase a set of patch ====== you have: / -- g -- h a -- b -- c -- d \ -- e -- f you want: / -- g -- h -- e -- f a -- b -- c -- d you should do: #git rebase --onto #apply commit between origin-start..origin-end onto destination-branch git rebase --onto h b f ====== Git rewrite commit date ====== export newdate=$(date +%s) git filter-branch -f --env-filter 'echo git author $GIT_AUTHOR_DATE -- $GIT_COMMITTER_DATE;export GIT_AUTHOR_DATE=$newdate; export GIT_COMMITER_DATE=$newdate;' origin/master..HEAD export bestdate=$(date +%s -d 'Sun Oct 18 22:42:42 CEST 2009') git filter-branch --commit-filter ' GIT_AUTHOR_NAME="Cedric GESTES"; GIT_AUTHOR_EMAIL="gestes@aldebaran-robotics.com"; GIT_AUTHOR_DATE=$bestdate; GIT_COMMITTER_NAME="${GIT_AUTHOR_NAME}"; GIT_COMMITTER_EMAIL="${GIT_AUTHOR_EMAIL}"; GIT_COMMITTER_DATE="${GIT_AUTHOR_DATE}"; git commit-tree "$@"; ' origin/master..HEAD ====== Git svn rebase on a git svn clone ====== git clone git@host/mygitsvnclone.git git svn init -s svn://host/mysvn git update-ref refs/remotes/trunk origin/master ====== Diff rename limit ====== if you have: git cherry-pick release-1.8 [10-10-25 warning: too many files (created: 622 deleted: 626), skipping inexact rename detection then increase the limit: git config --global diff.renamelimit 1000 [10-10-25 ====== Only push the current branch ====== git config --global push.default current