From 7d78ff81c861b164f3f722a18b37d75f37223209 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Mon, 16 Feb 2009 20:37:54 +0000 Subject: [PATCH] Add Stephen's git changes for the Feb 15th deadline. --- pep-0374.txt | 137 ++++++++++++++++++--------------------------------- 1 file changed, 47 insertions(+), 90 deletions(-) diff --git a/pep-0374.txt b/pep-0374.txt index b8e3ce385..169b38565 100644 --- a/pep-0374.txt +++ b/pep-0374.txt @@ -17,10 +17,6 @@ Post-History: 07-Nov-2008 This PEP is in the draft stages and is still under active development. -.. note:: - Final implementations for scenarios (sans `Coordinated Development of a New - Feature`_) are schedule to be completed by Feb. 15th. - Rationale ========= @@ -389,36 +385,14 @@ specify.:: echo '*~' >> ~/.gitignore echo '.msg' >> ~/.gitignore -If you use multiple branches, you can save a lot of space by putting -all objects in a common object store. This can be done physically, -by making them branches in a single repository. It can alternatively -be done logically, with the environment variables -``GIT_OBJECT_DIRECTORY`` (a single directory where new repository -objects will be written) and ``GIT_ALTERNATE_OBJECT_DIRECTORIES`` -(a colon-separated path -- on Windows, semicolon-separated -- of -directories containing read-only object stores to search). Note that -when making a local clone, git will hard-link objects rather than -creating copies if the OS supports that, which also saves space in -the child repository. Here's a complicated example:: - - # clone the trunk and py3k repositories - cd /path/to/myrepos - git clone git://code.python.org/python/trunk - git clone git://code.python.org/python/branches/py3k - # set up environment for my personal copies of the trunk and py3k - # they will read the objects in the pristine clones, but never write - # anything there export - # GIT_ALTERNATE_OBJECT_DIRECTORIES=/path/to/myrepos/trunk:/path/to/myrepos/py3k - git clone trunk trunk-sandbox - # set up environment for my personal copy of py3k - # read/write: if a file introduced in py3k is imported to trunk - # verbatim, the trunk sandbox will - # use the object created in the py3k sandbox - export GIT_OBJECT_DIRECTORY=/path/to/myrepos/trunk-sandbox - git clone py3k py3k-sandbox - -If you want more complexity, git clone has a plethora of options to -optimize space. +If you use multiple branches, as with the other VCSes, you can save a +lot of space by putting all objects in a common object store. This +also can save download time, if the origins of the branches were in +different repositories, because objects are shared across branches in +your repository even if they were not present in the upstream +repositories. git is very space- and time-efficient and applies a +number of optimizations automatically, so this configuration is +optional. (Examples are omitted.) One-Off Checkout @@ -507,13 +481,12 @@ The patches could be created with (empty files, renames, etc) that ordinary patch can't handle. git grabs "Stuff I did" out of the the commit message to create the file name 0001-Stuff-I-did.patch. See Patch Review below for a -description of the git-format-patch format.:: +description of the git-format-patch format. +:: # Get the mainline code. git clone git://code.python.org/python/trunk cd trunk - # Make a personal branch to keep the trunk ("master" branch) clean. - git checkout -b stuff # Edit some code. git commit -a -m 'Stuff I did.' # Create patch for my changes (i.e, relative to master). @@ -580,12 +553,9 @@ git # Assume the change to revert is the grandfather of a revision tagged "newhotness". git revert newhotness~2 - #if CONFLICTS - # Resolve conflicts if any. + # Resolve conflicts if any. If there are no conflicts, the commit + # will be done automatically by "git revert", which prompts for a log. git commit -m "Reverted changeset 9150dd9c6d30." - #else - # Edit log message, commit will be done automatically. - #endif git push @@ -686,6 +656,8 @@ start of the patch.:: cd trunk # Create a branch in case we don't like the patch. + # This checkout takes zero time, since the workspace is left in + # the same state as the master branch. git checkout -b patch-review # Download patch from bugs.python.org to submitted.patch. git am < submitted.patch @@ -823,7 +795,7 @@ revision IDs to merge. git ''' -In git I would have an "integration" workspace which contains all of +In git I would have a workspace which contains all of the relevant master repository branches. git cherry-pick doesn't work across repositories; you need to have the branches in the same repository. @@ -832,21 +804,16 @@ repository. # Assume patch applied to 2.7 in revision release27~3 (4th patch back from tip). cd integration git checkout release26 - # The "-x" option automatically notes which commit is being - # cherry-picked in the log. - git cherry-pick -x release27~3 + git cherry-pick release27~3 # If there are conflicts, resolve them, and commit those changes. # git commit -a -m "Resolve conflicts." # Run test suite. If fixes are necessary, record as a separate commit. # git commit -a -m "Fix code causing test failures." git checkout master - git cherry-pick -x release27~3 + git cherry-pick release27~3 # Do any conflict resolution and test failure fixups. # Revert Misc/NEWS changes. git checkout HEAD^ -- Misc/NEWS - # This creates a new commit on top of the cherry-pick. An alternative workflow - # would use the -n (aka --no-commit)flag to git-cherry-pick, and then commit - # here with an appropriate log message. git commit -m 'Revert cherry-picked Misc/NEWS changes.' Misc/NEWS # Push both ports. git push release26 master @@ -1090,53 +1057,43 @@ git :: cd trunk - # Actually, I wouldn't tag here in most cases; it's easy enough to get the - # appropriate revision to rewind to via git-show-branches. - git tag checkpoint - git checkout -b bug-0000 - # Edit some code, commit some changes. - git commit -a -m "Fixed urllib bug, part 1." - # Dang, we need to fix something lower level now. - # This is independent of urllib, so create a new branch at master. - git checkout -b fix-socket master + # Edit some code in urllib. + # Discover a bug in socket, want to fix that first. + # So save away our current work. + git stash # Edit some code, commit some changes. git commit -a -m "Completed fix of socket." - # Can't test urllib unless the socket fix is present. - # So we rebase on top of fix-socket (which is where we happen to be). - # git-rebase is interactive,so we resolve conflicts as we go along. - git rebase fix-socket bug-0000 - # Edit me some more code, commit some more fixes to bug-0000. + # Restore the in-progress work on urllib. + git stash apply + # Edit me some more code, commit some more fixes. git commit -a -m "Complete urllib fixes." - # Merge in the fixes. - git checkout master - git merge bug-0000 - # And push them to the public repository. + # And push both patches to the public repository. git push - # Bonus points: someone else fixes socket in the exact same way - # you just did, and landed that in the trunk. - # Merge their changes in and delete your now redundant thread. - # Note that we find this out because the git push fails with - # "not a fast forward." +Bonus points: suppose you took your time, and someone else fixes +socket in the same way you just did, and landed that in the trunk. In +that case, your push will fail because your branch is not up-to-date. +If the fix was a one-liner, there's a very good chance that it's +*exactly* the same, character for character. git would notice that, +and you are done; git will silently merge them. + +Suppose we're not so lucky:: + + # Update your branch. git pull git://code.python.org/public/trunk master - # Gag me, we got conflicts. - # Call the doctor, who says "you've got duplicate patchiosis". - # The second opinion is that it really is exactly what I had in fix-socket. - # OK, abandon my work, and clean up the bloody wreck of - # conflicts with the same mop: - git reset --hard checkpoint + + # git has fetched all the necessary data, but reports that the + # merge failed. We discover the nearly-duplicated patch. + # Neither our version of the master branch nor the workspace has + # been touched. Revert our socket patch and pull again: + git revert HEAD^ git pull git://code.python.org/public/trunk master - git rebase --onto master fix-socket bug-0000 - # If there were any conflicts, we fixed them during rebase. But - # there shouldn't be any, - # since we assumed the socket bug is independent of the urllib bug. - git checkout master - git merge bug-0000 - git push - # Clean up. We don't delete bug-0000 because the merge obsoleted it already. - git tag -d checkpoint - git branch -d fix-socket - # Now our HEAD has an up-to-date trunk and just the urllib fix. + +Like Bazaar and Mercurial, git has extensions to manage stacks of +patches. You can use the original Quilt by Andrew Morton, or there is +StGit ("stacked git") which integrates patch-tracking for large sets +of patches into the VCS in a way similar to Mercurial Queues or Bazaar +looms. Doing a Python Release