Add Stephen's git changes for the Feb 15th deadline.

This commit is contained in:
Brett Cannon 2009-02-16 20:37:54 +00:00
parent 8b5981fc10
commit 7d78ff81c8
1 changed files with 47 additions and 90 deletions

View File

@ -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