Thread (1 message) 1 message, 1 author, 2016-06-15

Re: git-bisect is magical

From: Junio C Hamano <hidden>
Date: 2016-06-15 22:42:16

walt [off-list ref] writes:
Linus Torvalds wrote:
[...]
quoted
So when you say "git checkout origin", it actually _switches_ to the
origin branch (which is just my state) and checks that out.
Please --> what am I switching *from* when I switch to 'origin'?
Short version: if you have only two branches "master" and
"origin", then obviously there is only one "the other one" ;-).

Longer version:

At the very beginning, you started your repository like this:

        $ git clone git://git.kernel.org/some/where mine
        $ cd mine

You can say:

	$ git branch

And you would see:

	$ git branch
        * master
          origin

So you have two branches, and you are on "master" right now.

Your working tree files are associated with one branch at any
moment, and "git branch" shows you which branch you are on.
That branch is "the current branch".  When you make your
commits, you will commit into that branch.  The commit-producing
commands include "git commit", "git am", "git pull", "git
merge", "git revert" and "git cherry-pick".  They all create a
new commit on your "current branch".  The difference among them
is where the commit you create takes the modifications from
(commit from the index file and the working tree, am from a
mailbox, pull and merge from a different branch, and revert and
cherry-pick from an existing commit).

You usually work in your "master" branch.  But you do not have
to.  Suppose you are working on maintaining some product, and
you have a couple of trivial bugfixes you can make and one
rather involved enhancement.  What you could do is to have more
than one branches, and use "master" for what are ready to be
consumed by other people, and another branch for your
developments.

Your repository at one point might look like this:

        $ git show-branch
        *  [master] trivial fix #2
         ! [devel] work in progress #3
        --
         + [devel] work in progress #3
         + [devel^] work in progress #2
         + [devel~2] work in progress #1
        +  [master] trivial fix #2
        +  [master^] trivial fix #1
        ++ [master~2] released frotz gadget

You are on the "master" branch, and committed two trivial fixes
on top of it since your last release.  But in the meantime you
found time to do independent enhancements, not yet finished but
slowly progressing.  You hope to be able to complete the
development and include that in the master branch eventually,
but not yet.

How you would end up to something like above would go like this:

 1. You have just released frotz gadget.  Your "master" branch
    is at that commit, and you do not have the "devel" branch
    yet.

 2. You are inspired by somebody to enhance frotz in a novel
    way.  You start hacking and accumulate some changes in the
    working tree files, but now you realize it will be a bigger
    task than you initially thought.  In the meantime, you got a
    couple of bug reports and you think you know how to fix them
    trivially.  But unfortunately, your working tree files are
    currently in a great mess.  Then:

        $ git checkout -b devel

    This creates a new branch ("devel") based on the current
    branch head (remember, you were on "master" branch), and
    switches to that new branch.  It is a short-hand for the two
    command sequence:

	$ git branch devel
        $ git checkout devel

    This takes your working tree changes with you, so at this
    point if you do "git diff", you will see your changes.  You
    commit this mess (do not worry about "presentable history"
    yet; you will be cleaning up the mess later anyway before
    you merge).

	$ git add new-files-you-created
	$ git commit -a -m 'work in progress #1'

 3. Now you can switch mood and can work on the trivial fixes.
    Go back to the "master" branch:

	$ git checkout master

    you'll notice that all the mess you made while working on
    devel has been cleaned up --- WIP edits are gone, and if you
    made new files for "devel" they are gone too.  You start
    from the state immediately after release, and work on fixes,
    and commit:

	$ edit for trivial fix number 1
	$ git commit -a -m 'trivial fix #1'
	$ edit for trivial fix number 2
	$ git commit -a -m 'trivial fix #2'

 4. Now fixes are out of your way, you can go back to work on
    the enhancements.  The same thing as step 3.

	$ git checkout devel
	$ edit / test / commit

Eventually what you do in your devel branch comes to maturity
and ready for public consumption.  How would you make sure when?
For that, you would create a throw-away test branch and try
things out:

	$ git branch -f test master
        $ git checkout test
        $ git merge 'development trial' test devel

This would create something like this:

        $ git show-branch
        !   [master] trivial fix #2
         !  [devel] work in progress #3
          * [test] development trial
        ---
	  + [test] development trial
         ++ [devel] work in progress #3
         ++ [devel^] work in progress #2
         ++ [devel~2] work in progress #1
        + + [master] trivial fix #2
        + + [master^] trivial fix #1
        +++ [master~2] released frotz gadget

You merged "devel" and "master" in "test" branch, so that you
can test your development along with the other fixes you had in
the "master" branch since your "devel" branch forked.  Try
things out and if you find the result satisfactory, then you
know what you have in "devel" is good for public consumption.

There are three ways to bring the "devel" into "master" at this
moment.  It depends on how much you care about clean history.

 A) just merge.

	$ git checkout master
        $ git pull . devel

    This is the simplest, but you would see all the real history
    in "devel" branch, things like "work in progress #n" commit
    log messages.

 B) refactor and linearize.

	$ git format-patch -k -m -o ./+redo master..devel

    This leaves a patchfile per commit in devel branch in +redo/
    directory.  You can edit the commit log message and patch
    just as if you are preparing them for e-mail submission to
    another project maintainer.  Once you are done editing:

	$ git checkout master
        $ git am -k -3 ./+redo/0*.txt

    to apply them on top of the master branch.

 C) linearize without refactoring.

	$ git checkout devel
        $ git rebase master
        $ git checkout master
        $ git pull . devel

    This "rebases" the development branch (the first two steps),
    and then pulls the result into the "master" branch (the
    rest).  It should give you the same result as approach B) if
    you do not edit your +redo/ files at all.

Once you are done, you can clean up by

	$ git branch -D test devel
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help