mirror of
				https://git.proxmox.com/git/mirror_zfs.git
				synced 2025-10-26 18:05:04 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			198 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			198 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| =========================== WHY USE GIT+TOPGIT? ==========================
 | |
| 
 | |
| Three major concerns were on our mind when setting up this project.
 | |
| 
 | |
|   o First we needed to structure the project in such a way that it would be
 | |
|     easy to rebase all of our changes on the latest official ZFS release
 | |
|     from Sun.  We absolutely need to be able to benefit from the upstream
 | |
|     improvements and not get locked in to an old version of the code base.
 | |
| 
 | |
|   o Secondly, we wanted to be able to easily manage our changes in terms
 | |
|     of a patch stack or graph.  This allows us to easily isolate specific
 | |
|     changes and push them upstream for inclusion.  It also allows us to 
 | |
|     easily update or drop specific changes based on what occurs upstream.
 | |
| 
 | |
|   o Thirdly we needed our DVCS to be integrated with the management of this
 | |
|     patch stack or graph.  We have tried other methods in the past such as
 | |
|     SVN+Quilt but have found managing the patch stack becomes cumbersome.
 | |
|     By using Git+TopGit to more tightly integrate our patches in to the repo
 | |
|     we expect several benefits.  One of the most important will be the
 | |
|     ability to easily work on the patch's with a distributed development
 | |
|     team, additionally the repo can track patch history, and we can utilize
 | |
|     Git to merge patches and resolve conflicts.
 | |
| 
 | |
| TopGit is designed to specifically address these concerns by providing 
 | |
| tools to simplify the handling of large numbers of interdependent topic 
 | |
| branches.  When using a TopGit aware repo every topic branch represents
 | |
| a 'patch' and that branch references its dependent branches.  The union
 | |
| of all these branches is your final source base.
 | |
| 
 | |
| ========================= SETTING UP GIT+TOPGIT ==========================
 | |
| 
 | |
| First off you need to install a Git package on your system.  For my
 | |
| purposes I have been working on a RHEL5 system with git version 1.5.4.5
 | |
| installed and it has been working well.  You will also need to go get
 | |
| the latest version of TopGit which likely is not packaged nicely so you
 | |
| will need to build it from source.  You can use Git to clone TopGit
 | |
| from the official site here and your all set:
 | |
| 
 | |
|         > git clone git://repo.or.cz/topgit.git
 | |
|         > make
 | |
|         > make install    # Default installs to $(HOME)
 | |
| 
 | |
| ========================== TOPGIT AND ZFS ================================
 | |
| 
 | |
| One you have Git and TopGit installed you will want to clone a copy of
 | |
| the Linux ZFS repo.  While this project does not yet have a public home
 | |
| it hopefully will some day.  In the meanwhile if you have VPN access to
 | |
| LLNL you can clone the latest official repo here.  Cloning a TopGit
 | |
| controlled repo is very similar to cloning a normal Git repo, but you
 | |
| need to remember to use 'tg remote' to populate all topic branches.
 | |
| 
 | |
|         > git clone git://eris.llnl.gov/zfs.git
 | |
|         > cd zfs
 | |
|         > tg remote --populate origin
 | |
| 
 | |
| Alternately, if you don't want to worry about using TopGit on your system
 | |
| you can simply clone the repo and then checkout the origin/top branch.  At
 | |
| this point you can simply create a new branch to track your changes.  You
 | |
| can then feed your patch back to the official repo maintainers to be merged
 | |
| in to the proper topic branches.
 | |
| 
 | |
| 	> git clone git://eris.llnl.gov/zfs.git
 | |
| 	> cd zfs
 | |
| 	> git checkout origin/top
 | |
| 	> git checkout -b <new_branch_name>
 | |
| 
 | |
| Now that you have the Linux ZFS repo the first thing you will probably 
 | |
| want to do is have a look at all the topic branches.  TopGit provides
 | |
| a summary command which shows all the branches and a brief summary for
 | |
| each branch obtained from the .topmsg files.
 | |
| 
 | |
|         > tg summary
 | |
|  0      feature-branch                  [PATCH] feature-branch
 | |
|         feature-commit-cb               [PATCH] feature commit cb
 | |
|         feature-zap-cursor-to-key       [PATCH] feature zap cursor to key
 | |
|         ...
 | |
| 
 | |
| By convention all TopGit branches are usually prefixed with 't/', however
 | |
| I have chosen not to do this for simplicity.  A different convention I have
 | |
| adopted is to tag the top most TopGit branch as 'top' for easy reference.
 | |
| This provides a consistent label to be used when you need to reference the
 | |
| branch which contains the union of all topic branches.
 | |
| 
 | |
| One thing you may also notice about the 'tg summary' command is it does
 | |
| not show the branches in dependent order.  This is done because TopGit allows
 | |
| each branch to express multiple dependencies as a DAC.  Initially this seemed
 | |
| like an added complication which I planned to avoid by just implementing a
 | |
| stack using the graph.   However, this ended up being problematic because
 | |
| with a stack when a change was made to a branch near the base, it was a
 | |
| very expensive operation to merge the change up to the top of the stack.
 | |
| By defining the dependencies as a graph it is possible to keep the depth
 | |
| much shallower thus minimizing the merging.  It has also proved insightful
 | |
| as to each patches actual dependencies.
 | |
| 
 | |
| To see the dependencies you will need to use the --graphviz option and pipe
 | |
| the result to dot for display.  The following command works fairly well for
 | |
| me.  Longer term it would be nice to update this option to use a preferred
 | |
| config options stored in the repo.
 | |
| 
 | |
|         > tg summary --graphviz | dot -Txlib -Nfontsize=8
 | |
| 
 | |
| ========================= UPDATING A TOPIC BRANCH ========================
 | |
| 
 | |
| Updating a topic branch in TopGit is a pretty straight forward but there
 | |
| are a few rules you need to be aware of.  The basic process involves 
 | |
| checking out the relevant topic branch where the changes need to be made,
 | |
| making the changes, committing the changes to the branch and then merging
 | |
| those changes in to dependent branches.  TopGit provides some tools to make
 | |
| this pretty easy, although it may be a little sluggish depending on how many
 | |
| dependent branches are impacted by the change.  Here is an example:
 | |
| 
 | |
|         > git checkout modify-topic-branch  # Checkout the proper branch
 | |
|         > ...update branch...               # Update the branch
 | |
|         > git commit -a                     # Commit your changes
 | |
|         > git checkout top                  # Checkout the top branch
 | |
|         > tg update                         # Recursively merge in new branch
 | |
| 
 | |
| Assuming you change does not introduce any conflicts your done.  All branches
 | |
| were dependent on your change will have had the changed merged in.  If your
 | |
| change introduced a conflict you will need to resolve the conflict and then
 | |
| continue on with the update.
 | |
| 
 | |
| ========================== ADDING A TOPIC BRANCH =========================
 | |
| 
 | |
| Adding a topic branch in TopGit can be pretty straight forward.  If your 
 | |
| adding a non-conflicting patch in parallel with other patches of the same
 | |
| type, then things are pretty easy and TopGit does all the work.
 | |
| 
 | |
|         > git co existing-topic-branch      # Checkout the branch to add after
 | |
|         > tg create new-topic-branch        # Create a new topic branch
 | |
|         > ...update .topmsg...              # Update the branch message
 | |
|         > ...create patch...                # Update with your changes
 | |
|         > git commit -a                     # Commit your changes
 | |
|         > git co dependent-topic-branch     # Checkout dependent branch
 | |
|         > tg depend add new-topic-branch    # Update dependencies 
 | |
|         > git checkout top                  # Checkout the top branch
 | |
|         > tg update                         # Recursively merge in new branch
 | |
| 
 | |
| If you need to add your patch in series with another change things are
 | |
| a little more complicated.  In this case TopGit does not yet support removing
 | |
| dependencies so you will need to do it by hand, as follows.
 | |
| 
 | |
|         > git co existing-topic-branch      # Checkout the branch to add after
 | |
|         > tg create new-topic-branch        # Create a new topic branch
 | |
|         > ...update .topmsg...              # Update the branch message
 | |
|         > ...create patch...                # Update with your changes
 | |
|         > git commit -a                     # Commit your changes
 | |
|         > git co dependent-topic-branch     # Checkout dependent branch
 | |
|         > ...update .topdeps...             # Manually update dependencies
 | |
|         > git commit -a                     # Commit your changes
 | |
|         > tg update                         # TopGit update
 | |
|         > git checkout top                  # Checkout the top branch
 | |
|         > tg update                         # Recursively merge in new branch
 | |
| 
 | |
| Once your done, I find it is a good idea view the repo using the  
 | |
| 'tg summary --graphviz' command and verify the updated dependency graph.
 | |
| 
 | |
| ========================= REMOVING A TOPIC BRANCH ========================
 | |
| 
 | |
| Removing a topic branch in TopGit is also currently not very easy.  To remove
 | |
| a dependent branch the basic process is to commit a patch which reverts all
 | |
| changes on the branch.  Then that reversion must be merged in to all dependent
 | |
| branches, the dependencies manually updated and finally the branch removed.
 | |
| If the branch is not empty you will not be able to remove it.
 | |
| 
 | |
|         > git co delete-topic-branch        # Checkout the branch to delete
 | |
|         > tg patch | patch -R -p1           # Revert all branch changes
 | |
|         > git commit -a                     # Commit your changes
 | |
|         > git checkout top                  # Checkout the top branch
 | |
|         > tg update                         # Recursively merge revert
 | |
|         > git co dependent-topic-branch     # Checkout dependent branch
 | |
|         > ...update .topdeps...             # Manually update dependencies
 | |
|         > git commit -a                     # Commit your changes
 | |
|         > tg delete delete-topic-branch     # Delete empty topic branch
 | |
| 
 | |
| Once your done, I find it is a good idea view the repo using the  
 | |
| 'tg summary --graphviz' command and verify the updated dependency graph.
 | |
| 
 | |
| ============================ TOPGIT TODO =================================
 | |
| 
 | |
| TopGit is still a young package which seems to be under active development
 | |
| by its author.  It provides the minimum set of commands needed but there
 | |
| are clearly areas which simply have not yet been implemented.  My short
 | |
| list of features includes:
 | |
| 
 | |
|   o 'tg summary --deps', option to display a text version of the topic
 | |
|     branch dependency DAC.
 | |
| 
 | |
|   o 'tg depend list', list all topic branch dependencies.
 | |
| 
 | |
|   o 'tg depend delete', cleanly remove a topic branch dependency.
 | |
| 
 | |
|   o 'tg create', cleanly insert a topic branch in the middle
 | |
|     of the graph and properly take care updating all dependencies.
 | |
| 
 | |
|   o 'tg delete', cleanly delete a topic branch in the middle
 | |
|     of the graph and properly take care updating all dependencies.
 | 
