Developers' side bar
<< | Page list | >>
1. Obtain repo into e.g. trunk directory
(if you are not developer, anonymous checkout can be obtained via:
Recent versions of ssh may complain about the keys the server uses. If so, add these lines to your .ssh/config file (or equivalent):
HostkeyAlgorithms +ssh-rsa PubkeyAcceptedAlgorithms +ssh-rsa
2. Setup your identity
git config --global user.name "Your Name Comes Here" git config --global user.email email@example.com
if you have more identities then use only local identification (inside trunk dir), e.g.:
Switch between trunk ("master") and branch ("2.2.x")
We suppose that the commit you want to backport is already inside of your repository, and it has SHA id. Now being in 2.2.x branch:
1) Patch-style method
add status info && commit && push.
2) Cherry-pick method
Cherry pick the commit, then
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:
The way how to get rid of it is using:
How to get rid of it? (more intricate answers)
A1: config git to push current branch only:
A2: push master(/branch) only:
A3: get rid of certain branch altogether:
Can I obtain kind-of-linearized numbering as in SVN? Generally no, but some info can be obtained via
... edit something
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>
# See diff: git diff // or more complex eg "git diff trunk..newfeature" or "git diff HEAD~10" # See current history with patches 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 committing 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.
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
For some operations your identity will be needed:
git config --global user.name "Your Name Comes Here" git config --global user.email firstname.lastname@example.org
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:
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
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
or tag it before delete
to make easy handle for potential checkout or diffs in the future (commits remain in repository, although the branch wont be visible now).
#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
To get the patch set, say of three last commits:
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.
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
When fetching stops with a perl error then remove all *.db in .git/svn/.caches.
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 ...
--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.