XFS git howto
Where is it?[edit | edit source]
A git server is setup on oss.sgi.com which is serving out of /oss/git. A user, git, has been setup with the home directory of /oss/git. The xfs trees are located under /oss/git/xfs. The main development tree is a bare repository under /oss/git/xfs/xfs.git. (So it has no checked out files just the .git database files at the top level) So far, it has a master, a mainline and an xfs-dev branch. The master branch is used for the checking in of development, it is mainline+latest XFS. xfs-dev will be set up to track ptools, checkins are currently closed to that branch.
For detailed information about the current available git trees, please see Getting the latest source code.
Checking out a tree:[edit | edit source]
$ git clone git+ssh://oss.sgi.com/oss/git/xfs/xfs/
( for local trees you can use the path directly, if the machine is running a git-daemon you can use git://, but that will not auto-setup push syntax )
this will clone the tree (all the commit objects), and checkout the HEAD branch (master for our case, other branches can be seen with git branch -a, to checkout a branch (local or remote) just use:
$ git checkout $branch
Tree Status:[edit | edit source]
$ git status # lists modified, unmerged and untracked files. $ git log # shows all commited modifications
( you can use git log $remote/branch to see the log of a remote )
Modifying files before checkins:[edit | edit source]
no need to mark files for modification, git will find out about them automagically, just edit them.
$ git add file # add $ git rm file # remove
Note: that if one uses "git-commit -a" or "git-finalize -a" then you don't have to add files which have been modified or deleted as git will detect them, you only have to add new files.
Commiting/checking in:[edit | edit source]
$ git commit
From man page - useful options:
-a|--all:: Tell the command to automatically stage files that have been modified and deleted, but new files you have not told git about are not affected.
--amend:: Used to amend the tip of the current branch. Prepare the tree object you would want to replace the latest commit as usual (this includes the usual -i/-o and explicit paths), and the commit log editor is seeded with the commit message from the tip of the current branch. The commit you create replaces the current tip -- if it was a merge, it will have the parents of the current tip as parents -- so the current top commit is discarded.
-s|--signoff:: Add Signed-off-by line at the end of the commit message.
I do like to git commit -asm "Commit message"
remember that a git commit, only commits to YOUR local tree, you then need to push things over:
General form is:
$ git push git://uri/of/the/other/rep +refspec $ git push oss
Where in xfs/.git/config it has the few lines:
[remote "oss"] url = ssh://oss.sgi.com/oss/git/xfs/xfs.git push = master
(Or modify the config file using "git remote add" mentioned below)
Going back in history - changing one's mind[edit | edit source]
[the STUPID (ptools) way]
$ git revert $mod
will introduce a new commit reverting $mod.
[ the OH GOD WE ARE DISTRIBUTED way (for mods not pushed anyway)]
if the mods to revert are the last n one:
$ git reset HEAD^n
if not (dangerous)
$ git rebase -i $mod^1 # considered harmfull read documentation !
Other related commands:
$ git reset # see doc for --hard
Tracking remote trees:[edit | edit source]
$ git remote add $name $uri # adds a remote tracking $ git remote update # updates all remotes $ git branch -a # shows all accessible branches ( including remotes in the $remote_name/ namespace )
$ git checkout -b $local_branch_name --track $remote_name/$remote_branch # creates a tracked local branch, git will warn whenever the remote adds commits.
Publishing one's tree:[edit | edit source]
give shell access to your tree, use git+ssh://machine/path or direct path
or
$ sudo git-daemon --export-all --base-path=/srv/git --base-path-relaxed --reuseaddr --user-path=public_git # exports all git trees found under ~/public_git and /srv/git
Or set up indetd etc.
Reviews and requesting them[edit | edit source]
Developer[edit | edit source]
From a git tree:[edit | edit source]
- publishes a git tree at git://dev/tree, containing his feature1 branch
- Requests a pull from the reviewer.
or
publishes a series of patches:[edit | edit source]
$ git format-patch $since_head # create ordered patches since head $since_head, i.e. on branch linus-create-ea, I'd $since_head would be linus/master $ git send-email --compose *.patch
Importing changes to our development tree[edit | edit source]
Reviewer - typically someone at SGI[edit | edit source]
From a git tree:[edit | edit source]
- Adds a remote locally called "dev":
$ git remote add dev git://dev/tree
- Looks at the differences between his tree (dev) and feature1:
$ git log HEAD...dev/feature1 # differences in both ways,
read man for more detail… List patches of commits from HEAD or dev/feature1 but not in both (A...B in one branch but not both) (A..B in branch B but not in A)
- Reviews the diffs: (-p adds commit change in patch form)
$ git log -p dev/feature1..HEAD
- For each commit he accepts, imports it to his tree, adding a
Signed-off-by: automatically:
Whilst in our own development tree, cherry-pick from the remote
$ git cherry-pick -s -e $commit # easily scriptable with git cherry
- The only trick there is putting the description into our preferred format,
with summary line with [XFS] prefix, body, and SGI-PV. I guess we'll need to do that manually.
- Pushes it to tree git+ssh://oss.sgi.com/oss/git/xfs/xfs.git
$ git push oss # if you've set up tracking remotes correctly
if not
$ git push git://chook/xfs/xfs-dev <refspec> # read man…
of form: git push repository <refspec> where <refspec> of form: The canonical format of a <refspec> parameter is `+?<src>:<dst>`; that is, an optional plus `+`, followed by the source ref, followed by a colon `:`, followed by the destination ref. The local ref that matches <src> is used to fast forward the remote ref that matches <dst>. If the optional plus `+` is used, the remote ref is updated even if it does not result in a fast forward update.
or
From emailed patches:[edit | edit source]
- From a plain patch:
$ git apply $patch # evil
- From a mailbox:
$ git am -s $mailbox # the way to go, adds Signed-off-by
In order to modify the commit description, it may work to apply the committed patches in another branch and then "cherry-pick -e" them into the development branch.
Lost your quilt ?[edit | edit source]
Hope you use underwear.
if not, you can look at many projects made of awesome:
guilt (written by Jeffpc, an XFS hacker):[edit | edit source]
quilt for git; similar to Mercurial queues Guilt (Git Quilt) is a series of bash scripts which add a Mercurial queues-like functionality and interface to git. The one distinguishing feature from other quilt-like porcelains, is the format of the patches directory. _All_ the information is stored as plain text - a series file and the patches (one per file). This easily lends itself to versioning the patches using any number of of SCMs.
stgit:[edit | edit source]
manage stacks of patches in a git repository stgit provides similar functionality to quilt (i.e. pushing/popping patches to/from a stack) on top of git.
These operations are performed using git commands and the patches are stored as git commit objects, allowing easy merging of the stgit patches into other repositories using standard git functionality.
Homepage: http://www.procode.org/stgit/
topgit[edit | edit source]
(house favourite, we may want to impose this one, but needs a bit of git knowledge to fully understand):
a Git patch queue manager TopGit manages a patch queue using Git topic branches, one patch per branch. It allows for patch dependencies and can thus manage non-linear patch series.
TopGit is a minimal layer on top of Git, which does not limit use of Git's functionality (such as the index). It rigorously keeps history until a patch is accepted upstream. It is also fully usable across distributed repositories.
Homepage: http://repo.or.cz/w/topgit.git