Show pageOld revisionsBacklinksBack to top This page is read only. You can view the source, but not change it. Ask your administrator if you think this is wrong. ====== git's cookbook for OpenSDE ====== I'll start by the most basic request, **PLEASE** read ''git's'' [[http://www.kernel.org/pub/software/scm/git/docs/|documentation]]! ''git'' is very well documented. If you still here I guess you decided that the official [[http://www.kernel.org/pub/software/scm/git/docs/|documentation]] was to tough for you. Then you can try a different kind of documentation, one focused on understanding how ''git'' works instead of how ''git'' is supposed to be used. * [[http://www.newartisans.com/blog_files/git.from.bottom.up.php|git from bottom up]] * [[http://eagain.net/articles/git-for-computer-scientists/|git for computer scientists]] but this guide is an OpenSDE-centric //cookbook//, so we will explain how to use ''git'' on our context. ===== OpenSDE structure ===== //OpenSDE// itself is composed by two [[http://git.or.cz/|git]] repositories, one for the [[http://git.opensde.net/opensde/opensde-nopast/|framework]] and one for the [[http://git.opensde.net/opensde/package-nopast/|packages database]]. These repositories currently don't include the past of the project which partially comes from [[http://www.rocklinux.net/svn/rock-linux/|RockLinux]]'s, [[http://svn.exactcode.de/t2/|T2]] and our own old [[http://subversion.tigris.org/|Subversion]] repository. The task of importing these commits into a new and more complete ''git'' repository has been postponed. In OpenSDE the //targets// are considered //sub-projects// so they have their own repositories. And we also support external repositories in ''package/repo''. ''sde up'' currently handles these external repositories when they are ''svn'' or ''git''. ==== The sde wrapper ==== On OpenSDE we provide a //silver bullet// tool which tries to hide some //version control system// specifics, to help in the //building// and //maintaining// processes, and to encourage some "recommended" practices while reducing the effort for the user. But ''sde'' can't (and should not) wrap the entire ''vcs'' functionality, just the most common actions. ''sde'' is designed to run from ''$PATH'', from any directory, understanding the context and using that knowledge to make user's life a bit easier. The ''sde'' wrapper takes the commands from the //working directory// you are using, so it's version independent. ===== Getting the tree ===== When you already have an //OpenSDE working tree//, and ''sde'' in your ''$PATH'', creating a new tree is very simple. $ cd somewhere $ sde new tree mynewtree And this will use ''git'' to get the //opensde repo// from the same location you were using before in ''somewhere/mynewtree'' and also the corresponding ''somewhere/mynewtree/package''. If you don't have //OpenSDE// yet the steps are the following (need ''git'' installed): $ cd somewhere $ git clone git://git.opensde.net/opensde/opensde-nopast mynewtree $ cd mynewtree $ git clone git://git.opensde.net/opensde/package-nopast package ==== Getting sde ==== It is a **very** good idea to install ''sde'' in your ''$PATH''. to do that go to the root of your //OpenSDE tree// and: $ ./bin/sde install This will symlink ''bin/sde'' of this //working tree// into your ''$HOME/bin'', which is supposed to be in the head of your ''$PATH''. Most distributions do this automatically, if the directory exists when you //log-in//. So logging out and back in may solve the issue. If not, you may want to add it on your own ''$HOME/.profile'' as: export PATH="$HOME/bin:$PATH" If you //cloned// ''opensde-nopast'' using ''git'' and you already put ''sde'' in your ''$PATH'', ''sde up'' will get ''package-nopast'' for you if it's still missing. ==== Staying up to date ==== In //OpenSDE// staying up to date is very easy, even when you have local commits which you don't want to send //upstream// (push) yet. But you have to remember ''git'', unlike ''svn'' needs your //working tree// clean of //uncommited// changes. $ sde up And your tree (including //framework//, //packages// and //targets//) will be up to day. To do it by hand you have to use ''git'' on each //repo//. (don't forget the //--rebase// part). $ git pull --rebase but when you are working on a local branch and you don't want upstream changes injected on it //yet// use: $ git fetch and ''origin/master'' will reflect the current //upstream// state, but your local //branch// wont be touched. ===== Branches ===== We inherited //subversion// from our predecessor. ''svn'' is great but not for us because: - you need to be //online// to work with it. - to merge from branch is //painful// We encourage people to work on public branches so we can all comment, contribute, and test before the final code hits the //trunk// (//tip// or //master//). But the problems shown above make people work on (private) //working trees// plenty of //uncommited// changes, and out of sync with //upstream//. ==== Creating a branch ==== The first question is, a //branch of what?// ... let see what we have $ git branch -a * master origin/HEAD origin/master origin/foobar Assuming you want a //local// branch (on which you could work) corresponding to //upstream//'s ''origin/foobar'' we create a //tracking// branch using: $ git checkout -b foobar origin/foobar This will bind the local //branch// "foobar" with the remote branch of the same name, in the //remote// named "origin". The other common case is to branch your current local "master" so you can: -commit all the //uncommited// changes you have in your messy //working directory// to be able to get in sync with upstream again. -push some commits upstream but not all, without loosing them. -move your work to a different //topic// branch. -start a new //topic// branch starting at this point. The first step for all of these cases is: $ git checkout -b mynewbranch and now you are at "mynewbranch" instead of "master", which can be confirmed using ''git branch''. If you are on case 1, the next step is to ''git add'', ''git rm'' and ''git mv'' what have have in git status, and make a monster git commit, or if you are terribly lazy ''git commit -a'' Then you can return to "master" using ''git checkout master''. Once back in "master", if you were on case 1, ''git pull --rebase'' should work. If you were in cases 2 or 3, ''git rebase -i origin/master^'' will let you remove those commits which you want in "mynewbranch" but not in "master" yet so you can push just a selected bunch. ==== Using branches ==== We don't like ''git merge'' (that's why we don't use use ''git pull''), we like to keep the commits //atomic//, not as a big monster commit as ''git merge'' produces. It's perfect (and recommended) to create a branch to update (and test) all the packages related to the last //foo// release. But the updates of each package shall remain separated. When one keeps branches, it's common to want to include on a branch a commit done in another branch. This is done using ''git cherry-pick <hash>'', but you don't need the whole //hash// of the //commit//, instead the first 6-8 characters are usually enough. $ git log otherbranch | less # to identify the commit $ git cherry-pick 1a2bcd Another common case is when you want to //cherry-pick// a range of commit, but ''git cherry-pick'' doesn't support ranges, so we need to loop. Assuming we want to merge from ''aabbcc'' (older) to ''ddeeff'' (newer), including both the shell loop would look like: $ for hash in $(git rev-list aabbcc^..ddeeff | tac); do > git cherry-pick $hash; > done The last case is when you want to //cherry-pick// many commit, in this case the easier way is to branch that other branch, and then rebase it interactively to yours, so you remove those commits you don't want. $ git checkout the_other_branch $ git checkout -b a_new_one # make a copy of that other branch $ git rebase -i the_one_im_working_on # to remove those commits you don't want $ git branch -d the_one_im_working_on # careful! this is a delete! $ git checkout the_other_branch # you can't rename the current, so go out $ git branch -m a_new_one the_one_im_working_on # the rename Another way of working with ''git'' (more like a complementary way to //branches//) is presented at [[git-stash]]. ==== Pushing a branch ==== To //push// a branch means to send your local commits upstream ==== Deleting a branch ==== misc/git-doc.txt Last modified: 2018/08/14 11:25by 127.0.0.1