stg series: Explain the list format better
[stgit] / Documentation / tutorial.txt
index 103f3e4..283b358 100644 (file)
@@ -103,10 +103,11 @@ And voilĂ  -- the patch is no longer empty:
            _main()
        finally:
 
-(I'm assuming you're already familiar with patches like this from Git,
-but it's really quite simple; in this example, I've added the +$$print
-'My first patch!'$$+ line to the file +stgit/main.py+, at around line
-171.)
+(I'm assuming you're already familiar with
+htmllink:http://en.wikipedia.org/wiki/Diff#Unified_format[unified
+diff] patches like this from Git, but it's really quite simple; in
+this example, I've added the +$$print 'My first patch!'$$+ line to the
+file +stgit/main.py+, at around line 171.)
 
 Since the patch is also a regular Git commit, you can also look at it
 with regular Git tools such as manlink:gitk[].
@@ -430,23 +431,284 @@ patches as patches.
 Workflow: Tracking branch
 =========================
 
+In the 'Development branch' workflow described above, we didn't have
+to worry about other people; we're working on our branch, they are
+presumably working on theirs, and when the time comes and we're ready
+to publish our branch, we'll probably end up merging our branch with
+those other peoples'. That's how Git is designed to work.
 
-Rebasing a patch series
------------------------
+Or rather, one of the ways Git is designed to work. An alternative,
+popular in e.g. the Linux kernel community (for which Git was
+originally created), is that contributors send their patches by e-mail
+to a mailing list. Others read the patches, try them out, and provide
+feedback; often, the patch author is asked to send a new and improved
+version of the patches. Once the project maintainer is satisfied that
+the patches are good, she'll 'apply' them to a branch and publish it.
 
-TODO:: rebase, ...
+StGit is ideally suited for the process of creating patches, mailing
+them out for review, revising them, mailing them off again, and
+eventually getting them accepted.
 
 
 Getting patches upstream
 ------------------------
 
-TODO:: export, mail, ...
+We've already covered how to clone a Git repository and start writing
+patches. As for the next step, there are two commands you might use to
+get patches out of StGit: stglink:mail[] and stglink:export[].
+stglink:export[] will export your patches to a filesystem directory as
+one text file per patch, which can be useful if you are going to send
+the patches by something other than e-mail. Most of the time, though,
+stglink:mail[] is what you want.
+
+NOTE: Git comes with tools for sending commits via e-mail. Since StGit
+patches are Git commits, you can use the Git tools if you like them
+better for some reason.
+
+NOTE: For exporting single patches -- as opposed to a whole bunch of
+them -- you could also use stglink:show[] or stglink:diff[].
+
+Mailing a patch is as easy as this:
+
+  $ stg mail --to recipient@example.com <patches>
+
+You can list one or more patches, or ranges of patches. Each patch
+will be sent as a separate mail, with the first line of the commit
+message as subject line. Try mailing patches to yourself to see what
+the result looks like.
+
+NOTE: stglink:mail[] uses +sendmail+ on your computer to send the
+mails. If you don't have +sendmail+ properly set up, you can instruct
+it to use any SMTP server with the +$$--smtp-server$$+ flag.
+
+There are many command-line options to control exactly how mails are
+sent, as well as a message template you can modify if you want. The
+man page has all the details; I'll just mention two more here.
+
++$$--edit-cover$$+ will open an editor and let you write an
+introductory message; all the patch mails will then be sent as replies
+to this 'cover message'. This is usually a good idea if you send more
+than one patch, so that reviewers can get a quick overview of the
+patches you sent.
+
++$$--edit-patches$$+ will let you edit each patch before it is sent.
+You can change anything, but note that you are only editing the
+outgoing mail, not the patch itself; if you want to make changes to
+the patch, you probably want to use the regular StGit commands to do
+so. What this 'is' useful for, though, is to add notes for the patch
+recipients:
+
+----------------------------------------------------------------------
+From: Audrey U. Thor <author@example.com>
+Subject: [PATCH] First line of the commit message
+
+The rest of the commit message
+
+---
+
+Everything after the line with the three dashes and before the diff is
+just a comment, and not part of the commit message. If there's
+anything you want the patch recipients to see, but that shouldn't be
+recorded in the history if the patch is accepted, write it here.
+
+ stgit/main.py |    1 +
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+
+
+diff --git a/stgit/main.py b/stgit/main.py
+index e324179..6398958 100644
+--- a/stgit/main.py
++++ b/stgit/main.py
+@@ -171,6 +171,7 @@ def _main():
+     sys.exit(ret or utils.STGIT_SUCCESS)
+
+ def main():
++    print 'My first patch!'
+     try:
+         _main()
+     finally:
+----------------------------------------------------------------------
+
+
+Rebasing a patch series
+-----------------------
+
+While you are busy writing, submitting, and revising your patch
+series, other people will be doing the same thing. As a result, even
+though you started writing your patches on top of what was the latest
+history at the time, your stack base will grow ever more out of date.
+
+When you clone a repository,
+
+  $ stg clone http://homepage.ntlworld.com/cmarinas/stgit.git stgit
+
+you initially get one local branch, +master+. You also get a number of
+'remote' branches, one for each branch in the repository you cloned.
+In the case of the StGit repository, these are
++remotes/origin/stable+, +remotes/origin/master+, and
++remotes/origin/proposed+. +remotes+ means that it's not a local
+branch, just a snapshot of a branch in another repository; and
++origin+ is the default name for the first remote repository (you can
+set up more; see the man page for +git remote+).
+
+Right after cloning, +master+ and +remotes/origin/master+ point at the
+same commit. When you start writing patches, +master+ will advance,
+and always point at the current topmost patch, but
++remotes/origin/master+ will stay the same because it represents the
+master branch in the repository you cloned from -- your 'upstream'
+repository.
+
+Unless you are the only one working on the project, however, the
+upstream repository will not stay the same forever. New commits will
+be added to its branches; to update your clone, run
+
+  $ git remote update
+
+This will update all your remote branches, but won't touch your local
+branches. To get the latest changes into your local +master+ branch,
+use stglink:rebase[]:
+
+  $ stg rebase remotes/origin/master
+
+This command will do three things:
+
+  1. Pop all patches, so that your local branch (+master+, in this
+     example) points at the stack base. This is the same commit that
+     +remotes/origin/master+ pointed at at the time you started
+     writing your patches.
+
+  2. Set the stack base to the given commit (the current, updated
+     value of +remotes/origin/master+).
+
+  3. Push the patches that were popped in the first step.
+
+The end result is that your patches are now applied on top of the
+latest version of +remotes/origin/master+.
+
+The primary reason for rebasing is to reduce the amount of conflicts
+between your work and others'. If one of your patches changes the same
+part of the same file as a patch someone else has written, you will
+get a conflict when you run stglink:rebase[] the next time after the
+other person's patch has been accepted upstream. It is almost always
+less work to rebase often and resolve these one at a time, rather than
+a whole lot at once. After all, you have to rebase eventually; if you
+mail out patches that are based on an outdated branch, everyone who
+tries to apply them has to resolve the conflicts instead. There are
+more effective ways to get popular.
+
+
+When your patches are accepted
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If and when some or all of your patches are accepted upstream, you
+update and rebase just like usual -- but be sure to use the
++$$--merged$$+ flag to stglink:rebase[]:
+
+  $ git remote update
+  $ stg rebase --merged remotes/origin/master
+
+This flag makes the rebase operation better at detecting that your
+patches have been merged, at some cost in performance.
+
+The patches that had been merged will still be present in your patch
+stack after the rebase, but they will be empty, since the change they
+added is now already present in the stack base. Run stglink:clean[] to
+get rid of such empty patches if you don't want them hanging around:
+
+  $ stg clean
 
 
 Importing patches
 -----------------
 
-TODO:: import, ...
+While you are busy producing patches, there's hopefully someone -- the
+'maintainer' -- at the other end who recieves them and 'applies' them
+to her Git tree, which is then published for all (or parts of) the
+world to see.
+
+It's perfectly fine for this person to not have the foggiest idea what
+StGit is. In that case, she'll probably apply your patches with
+something like +git am+, and everything will just work, exactly as if
+you'd used Git to send those patches. But she might be an StGit user
+too, in which case she might use stglink:import[].
+
+There are basically four kinds if stuff you can import with
+stglink:import[]:
+
+  1. A patch in a file.
+
+  2. Several files containing one patch each, and a 'series' file
+     listing those other files in the correct order.
+
+  3. An e-mail containing a single patch.
+
+  4. A mailbox file (in standard Unix +mbox+ format) containing
+     multiple e-mails with one patch in each.
+
+
+Importing a plain patch
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Importing a plain patch, such as produced by e.g. GNU +diff+, +git
+diff+, +git show+, stglink:diff[], or stglink:show[], is very easy.
+Just say
+
+  $ stg import my-patch
+
+and you'll have a new patch at the top of your stack.
+
+If you don't give a file name on the command line, stglink:import[]
+will read the patch from its standard input -- in other words, you can
+pipe a patch to it directly from the command that produces it.
+
+By default, the new patch's name will be taken from the file name, and
+its commit message and author info will be taken from the beginning of
+the patch, if they are there. However, there are command line switches
+to override all of these things; see the man page for details.
+
+
+Importing several patches at once
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Some programs -- among them stglink:export[] -- will create a bunch of
+files with one patch in each, and a 'series' file (often called
++series+) listing the other files in the correct order. Give
++$$--series$$+ and the name of the series file to stglink:import[],
+and it will import all the patches for you, in the correct order.
+
+
+Importing a patch from an e-mail
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Importing a patch from an e-mail is simple too:
+
+  $ stg import --mail my-mail
+
+The e-mail should be in standard Git mail format (which is what e.g.
+stglink:mail[] produces) -- that is, with the patch in-line in the
+mail, not attached. The authorship info is taken from the mail
+headers, and the commit message is read from the 'Subject:' line and
+the mail body.
+
+If you don't give a file name, the mail will be read from the standard
+input. This means that, if your mail reader supports it, you can pipe
+a mail directly to +stg import $$--mail$$+ and the patch will be
+applied.
+
+
+Importing a mailbox full of patches
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Finally, in case importing one patch at a time is too much work,
+stglink:import[] also accepts an entire Unix +mbox+-format mailbox,
+either on the command line or on its standard input; just use the
++$$--mbox$$+ flag. Each mail should contain one patch, and is imported
+just like with +$$--mail$$+.
+
+Mailboxes full of patches are produced by e.g. stglink:mail[] with the
++$$--mbox$$+ flag, but most mail readers can produce them too, meaning
+that you can copy all the patch mails you want to apply to a separate
+mailbox, and then import them all in one go.
 
 
 Other stuff that needs to be placed somewhere