Go to page:

Search:   Help

Developers' side bar

Selected categories


Shared groups



Categories: Development, Tips
<< | Page list | >>

Git usage

Setup - you need developer account and provide your public ssh key before all this.

1. Obtain repo into e.g. trunk directory
git clone git@git.lyx.org:lyx trunk
(if you are not developer, anonymous checkout can be obtained via: git clone git://git.lyx.org/lyx)
2. Setup your identity
git config --global user.name "Your Name Comes Here"
git config --global user.email you@yourdomain.example.com
if you have more identities then use only local identification (inside trunk dir), e.g.:
git config --local user.email developer@lyx.org

Simple SVN-like model for trivial changes of the tree

Choose whether you want use trunk or branch

Switch between trunk ("master") and branch ("2.0.x")
git checkout master  //2.0.x

Update tree

git pull --rebase  //update from public repo and put local changes on top (rebase)

Commit changes

git commit  //(just local commit in your tree)
git pull --rebase  //update from public repo and put local changes on top - this will avoid one pointless "merge commit")
git push  //send it to the public repository

Backporting changes to branch

We suppose that the commit you want to backport is already inside of your repository, and it has SHA id. Now being in 2.0.x branch:

1) Patch-style method

git show SHA | git apply  //git-apply does not allow fuzzines, so may try classical "patch"
add status info && commit && push.

2) Cherry-pick method Cherry pick the commit, then git commit -a --amend to add needed changes. Then commit && push.

3) Branch/merge based. Look elsewhere.


Spurious merge commits

After committing your work on top of master and pulling the news from the public repo you usually get empty merge commit:

Merge branch 'master' of git.lyx.org:lyx

The way how to get rid of it is using: git pull --rebase.

Pushing errors:

I try to push my changes, but git complains about the other branch (usually not being up-to-date), eg:

! [rejected] 2.0.x -> 2.0.x (non-fast forward)
error: failed to push some refs to 'git@lyx:lyx'

How to get rid of it? (more intricate answers)

A1: config git to push current branch only:

git config push.default current  //From now on, 'git push' will by default only try to push the branch you are on if there is a matching branch at the server.

A2: push master(/branch) only:

git push origin master  //given that the remote is called 'origin'. See 'git remote -v'

A3: get rid of certain branch altogether:

git branch -D 2.0.x

Linear numbering:

Can I obtain kind-of-linearized numbering as in SVN? Generally no, but some info can be obtained via
git describe  //-> 2.0.0-1397-g8be1845

Merge conflicts:

Using branches. Shall be used for more complex work.

git checkout -b myfeature
... edit something
git commit -a
git push origin myfeature:master


git rebase master    //(on branch myfeature,  rebase your feature on top of master

#If we don't stick to the linear master branch idea, then you can first merge your branch into master
git checkout master  
git merge myfeature
git push

Pushing whole branch as a single commit into trunk

git merge myfeature --squash   //on master
git commit
<edit the commit log to your likings>

Other useful commands for newcomers to git

# See diff:
git diff   // or more complex eg "git diff trunk..newfeature" or "git diff HEAD~10"

# See current history with pacthes
git log -p   //add "file" to see only commits touching "file"; --no-merges avoid empty merge commits

# Add new files to repository
git add files

#to throw local changes away from branch:
git checkout -f

#to restore unintentionally removed file: 
git checkout deleted.file

#reverting file two commits back:
git checkout HEAD~2 file

#display available branches (the current has asterisk)
git branch -a

#now we will go 10 patches back (ie somewhere before you started work on your own)
git checkout master~10

#undo last commit or merge
git reset HEAD^          // but let the files modified as before commiting
git reset --hard HEAD^   // let the files identical to HEAD^ (git diff==null)

Rest of this page is obsolete. We moved from svn to git so all material based on svn-git is no more helpful.

See LyXGit as well.


There are various reason why one start to use git. Firstly you don't need commit access to svn to maintain your own diverged tree from the official one, secondly git itself is more powerfull to maintain more branches - including merging capabilities, visualizing, hardlinking etc.

Using git-svn

To start your work you will need installed subversion for fetching, git and git-svn (git-svn script can be part of your git package by default, for its working you will need subversion perl support enabled and also libwww-perl package).

Warning: In newer git installations on linux you need to use git svn ... commands instead of git-svn ... .

Setup branch with svn-git

For some operations your identity will be needed:

git config --global user.name "Your Name Comes Here"
git config --global user.email you@yourdomain.example.com

Now choose what part do you want to import. This will be usually trunk, but maybe you want the branches (look on special switches for init to specify this) or the whole repo.

#Choose the directory for your branch, eg:
cd ~/git/lyx/trunk

#prepare directory
git-svn init svn://svn.lyx.org/lyx/lyx-devel/trunk

#fetching from revision e.g. 35236
git-svn fetch -r 35236

#if you have write access to svn, you probably want to use svn dcommit for commit, 
#you will be asked from subversion about the username&pass for the first time
#of commiting. from then using svn://svn.lyx.org/ is enough for write access.

#updating to the latest revision
git-svn rebase

For fetching the whole history, see the section Full SVN mirror

Now you can denote your own branch if you want:

git-checkout -b branch_name

Working with one branch

Usually the cycle will look like this:

#editing changes
vi blabla.cpp

#commiting changes
#now your changes will be the in the last-log
git commit -a

#updating from svn (something like "svn up")
#after this your changes will be again in the last log as before updating, 
#as they are reverted
#and after updating again merged. remember to commit before updating.
git-svn rebase

#you can do this regularly, because if there is some merge conflict 
#you can take the whole operation back by:
git rebase --abort

#or you can edit the conflicts now
#to see where the conflict are:
git diff
#repair it
vi conflict.file
#tell git conflict is resolved
git update-index conflict.file
#continue with rest of patches
git rebase --continue

#if you don't like commiting before updating, you can study these commands:
git-add . ; git-commit -m "temporary commit"
git-svn rebase
git-reset --mixed HEAD^

#to throw local changes away from branch:
git checkout -f

#to restore unintentionally removed file: 
git checkout deleted.file

#reverting file two commits back:
git checkout branchname~2 file

Working with more branches

Imagine you denoted your branch at the beginning 'newfeature'. Now you would like to make some comparisons between current trunk and your locally commited code without changing anythning in newfeature. One possibility is to coin new branch, say trunk, and use this branch simultaneously.

#display available branches (the current has asterisk)
git branch

#now we will go 10 patches back (ie somewhere before you started work on your own)
git checkout master~10

#now you can look, that you moved into some (probably) unnamed branch, 
#which is trunk before you started work or even denoting it by newfeature.
git branch

#you can name this branch trunk
git checkout -b trunk

#and make the trunk up to date;look on 'git log' and 'git branch' after 
git-svn rebase

#now you can switch back to your devel branch
git checkout newfeature

#you can see the difference between trunk and newfeature; 
#git-svn is still usable here in newfeature...
git diff trunk..newfeature

#switch from current branch with local changes to another_branch with 3-way merge:
git checkout -m another_branch

By checkout -b you can create many branches and merge them back (possiby more branches in one merge etc.) - look into manual. To have graphical view of branching and history you can use simpler gitk or more sophisticated qgit.

As branches are very cheap their number increase, and most of them is not used anymore. You can either delete the branch by

git branch -d mybranch

or tag it before delete

git tag tagofmybranch

to make easy handle for potential checkout or diffs in the future (commits remain in repository, although the branch wont be visible now).

Other git examples

#See all commits touching particular file (-p for printing diffs too)
git whatchanged file

#undo last commit or merge
git reset HEAD^

#see symmetric differences (in commits) between two branches
git log trunk...mybranch

#see commits which touched particular file
git log path-or-files

#the same but only in last two weeks
git log --since="2 weeks ago" -- files

#git log -p                  #show last commits
#git show HEAD~20..HEAD^^    #show the interval of [current-20;current-2] of commits

#Applying patch(commit) from a different branch
git-cherry-pick -n <commit_number>
or complicated way
git diff commit..commit^|git apply
or revert another commit
git show commit|git apply --reverse

#Searching in the commit history
#you can obtain the list of commits where STRING were in changed part (ie +/-)
git log --pretty=oneline  -S'STRING'
#or you can use classical blame, but note that git blame is much more sophisticated. 
#It is able to detect movement of lines between parts of file 
#or even files when this  movement happens during one commit. So
git blame file
#is able to step origin of lines even through the shifts like the big renaming 
#calamity of smallfile.C -> SmallFile.cpp etc.
#You can consult blame parameters to refine these shifts detections.

#Searching the bug via bisect.
#Usual case you have some error in the current tree (HEAD).
#This will reset the old good/bad intervals
git bisect reset
git bisect start
#start defining new interval
git bisect bad HEAD
#now go back in history to get some revision which is ok.
git checkout HEAD~50
#suppose you are now in revision which was ok
git bisect good HEAD
# that created new border of good-bad interval and switch you to the half 
#of the good-bad interval.
# Simply reiterate with the proper good/bad flags till the end, 
# where git give you the log of the problematic commit.

#Postponing your changes for a while, getting back to fresh tree 
#and then getting back tree with your changes
git stash              ##saving it, now you are on clean tree
git stash show -p      ##showing the diff in stash against the current tree
... some work ...
git stash apply        ##get things from stash back to the tree
git stash clear

#Repair last commit
git commit --amend                  #Only change commit message
git add file; git commit --amend    #Repair some change in file

You can create .gitignore file in the top level of branch with list of ignored (see git status) files, you can also use wildcards.

If you like colors you can configure git for them:

git config --global color.diff auto
git config --global color.status auto
git config --global color.branch auto

Contributing back

To get the patch set, say of three last commits:

git-format-patch -3 --stdout

If you have also write access to svn you can directly use git-svn dcommit.


This is just shortcut for quick start with using git. git itself is much more powerful tool, so you should look on other links for svn+git:

and the many guides to the git itself as it is possible you want more branches, centralized repo for merging them together etc.

Full SVN archive mirror

In case you want to have the whole revision history with all branches you can download the archive converted via git-svn here (or use one of ftp mirrors, since this is a huge thing):

The archive was get via:

git svn clone svn://svn.lyx.org/lyx/lyx-devel/  -T trunk -b branches -t tags

Note that there is a slight difference in keeping the tree up-to-date compared to trunk-only tree - you need to call also git-svn fetch to get all branch-revisions, not only git-svn rebase .

When fetching stops with a perl error then remove all *.db in .git/svn/.caches.

Seeking bugs in this archive via bisection

Suppose you have regression on 1.6.6 compared to 1.6.5. So you go to 1.6.6:

$ git checkout tags/lyx-1_6_6   #see "git branch -r" for possible tags
$ git bisect start              #start bisection
$ git bisect bad                #we know here is the bug
$ git checkout tags/lyx-1_6_5   #go to tree tagged 1.6.5
$ git checkout HEAD~200         #alternatively to 1.6.5 - go 200 commits back if you have an idea where's the problem
$ git bisect good               #we know this was ok in 1.6.5 / 200 steps back

- now bisect will checkout to the commit in the middle of 1.6.5..1.6.6 interval (or sometimes to a merge base for the first time).

$ make && src/lyx               #take your coffee
$ git bisect bad                #in case the bug is still there
$ git bisect good               #in case the bugs no more there

... you iterate through these two steps when finally git spits on you the problematic commit ...

Using the Git mirror repository --does not work anymore

--beware this source is quite unreliable as far as being up-to-date is concerned--

Instead of working with the lyx-devel subversion repository directly (as shown above), you can simply use the unofficial Git mirror at repo.or.cz. In this case you can use the normal Git workflow and commands, such as "git pull", "git fetch" and "git rebase".

To clone that repository, use:

git clone git://repo.or.cz/lyx-svn.git

Currently (2009-04-20), you will need ca. 420 MB (with ~360 MB for the .git repository files and the rest for the checked out sources).

Switch to branch can be done via:

git checkout origin/BRANCH_1_6_X

Then proceed using your favorite Git tutorial, but note that you cannot push into the mirror repository.

Category: Development, Tips

Edit - History - Print - Recent Changes - All Recent Changes - Search
Page last modified on 2012-12-02 16:56 CET