Developers' side bar Selected categories Edit Links |
Devel /
GitCategories: Development, Tips << | Page list | >>Git usageTable of contents (hide)
1. 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 )
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 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
2. change to the lyx directorycd lyx
3. Simple SVN-like model for trivial changes of the tree3.1 Choose whether you want use trunk or branchSwitch between trunk ("master") and branch ("2.2.x")
git checkout master //2.2.x
3.2 Update treegit pull --rebase //update from public repo and put local changes on top (rebase)
3.3 Commit changesgit 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
3.4 Backporting changes to branchWe 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 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 3) Branch/merge based. Look elsewhere. 3.5 ProblemsSpurious merge commitsAfter 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: Pushing errors:I try to push my changes, but git complains about the other branch (usually not being up-to-date), eg: ! [rejected] 2.2.x -> 2.2.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.2.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:4. Using branches. Shall be used for more complex work.git checkout -b myfeature
... edit something
git commit -a
git push origin myfeature:master
4.1 Merginggit 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 trunkgit merge myfeature --squash //on master git commit <edit the commit log to your likings> 5. 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 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) 6. 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. 7. PreliminaryThere 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. 8. Using git-svnTo 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 8.1 Setup branch with svn-gitFor 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
8.2 Working with one branchUsually 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 8.3 Working with more branchesImagine 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). 8.4 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 8.5 Contributing backTo 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. 8.6 ConclusionThis 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. 9. Full SVN archive mirrorIn 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. 10. Seeking bugs in this archive via bisectionSuppose 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 ... 11. 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 |