Git development
 help / color / mirror / Atom feed
* Re: [gitweb feature request] Release snapshots with vX.X.X tags
From: Bram Neijt @ 2009-11-08 21:08 UTC (permalink / raw)
  To: Git mailing list
In-Reply-To: <7vbpjcetlp.fsf@alter.siamese.dyndns.org>

I was going to comment inline but I think the general question can be
read as "why would you want this?". For me it's just an extra bit of
automation. It would keep me from having to make release tarballs. I
would just refer all the users to a gitweb snapshot link of the "v..."
tag. Having a release tarball with "projectname-version" with a single
directory called "projectname-version/" in it is just good practice if
you ask me.

Therefore it would benefit any developer like me :D : a spare time
hobbyist who likes to automate as much of the administrative tasks, that
go into running an open source project, as possible.

Greets,
  Bram

PS I've found that cgit: http://hjemli.net/git/cgit/
has this feature, so I'm probably going to give that a try and get back
to you if I find any problems with it (the feature that is).

On Sun, 2009-11-08 at 10:53 -0800, Junio C Hamano wrote:
> Bram Neijt <bneijt@gmail.com> writes:
> 
> > I would like to create release snapshots with a git tag like "v0.0.1".
> > For proper Debian packaging, a release snapshot of tag "v0.0.1" would
> > have to be named "project-0.0.1.tar.gz" and contain a single directory
> > with "project-0.0.1/" in the archive.
> 
> What the intended audience of this feature?  IOW,
> 
>  - who are going to "click" such a link on gitweb to obtain
>    project-0.0.1.tar.gz with project-0.0.1/?
> 
>  - how are they going to use that tarball?
> 
> I somehow suspect that they won't be the official Debian distro packagers.
> 
> Most likely they actually have a clone of the upstream project (how else
> they can stay up to date?  In addition they would want to track their own
> changes), so it would be more efficient for them to generate such a
> tarball from a tag, and more importantly, doing it locally means that they
> can they can verify the tag (and the whole history leading to it) before
> doing so, instead of relying on somebody else's gitweb.
> 
> You could be a mere Debian user who produces a *.deb for his own use out
> of such tarball, and in such a case you are a lot less likely be tracking
> the project (meaning, reading the history and keeping track of fixed bugs,
> new regressions and such) than just getting a snapshot that happens to be
> there and building it blindly, and I can understand it would be nicer if
> you did not have to unpack, rename and regenerate an archive.
> 
> Also, whose gitweb installations are you envisioning to enable this new
> feature?  Are you going to convince all the gitweb administrators of
> projects packaged by Debian (and derivatives) that have gitweb, and what
> are the incentive for these upstream projects to do so?  I would guess
> that most of the upstream projects do not consider Debian as their sole
> target distribution, and it would be a tough sell if changing the snapshot
> name to suit Debian breaks some other distro's (or human users) needs.
> 
> Jakub is polishing Mark's patch to change the snapshot name and contents
> hierarchy, but I think it won't satisfy Debian's naming guideline (it will
> have v0.0.1, not 0.0.1 in the name).  Changing the series's default to
> drop 'v' from the beginning of the tagname when the rest of it consists of
> all digits and dots would not be a correct solution, as Debian is not the
> only system in the world and other people may want different naming rules.
> 
> In order to make his series useful for your objective, it probably would
> require a bit more customizability, but because I cannot tell whom such a
> feature is really trying to help, and what the deployment plans are, I
> cannot judge if extra complexity to add such a customizability is worth
> it.  Also because there will be conflicts in the desired archive format
> ("Distro X people want this kind of archive, distro Y people want this
> different kind"), the choice somehow how to come from whoever is clicking
> the link, not from the gitweb administrator, and it probably would mean
> the codepath involved would need a lot more careful audit than just a
> server only "this gitweb installation would use this format"
> configuration.
> --
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [RFC/PATCH 1/4] Teach the --all option to 'git fetch'
From: Paolo Bonzini @ 2009-11-08 21:08 UTC (permalink / raw)
  To: git
In-Reply-To: <4AF6E7A6.5060209@gmail.com>

On 11/08/2009 04:45 PM, Björn Gustavsson wrote:
> 'git remote' is meant for managing remotes and 'git fetch' is meant
> for actually fetching data from remote repositories. Therefore, it is
> not logical that you must use 'git remote update' to fetch from
> more than one repository at once.
>
> Add the --all option to 'git fetch', to tell it to attempt to fetch
> from all remotes. Also, if --all is not given, the<repository>
> argument is allowed to be the name of a group, to allow fetching
> from all repositories in the group.
>
> Other options except -v and -q are silently ignored.

I'm not sure about the naming of the option.  The reason is that while 
there is no "git remote push", it makes sense (at least in this case 
symmetry) between "git fetch" and "git push".  I would love to have a 
way to push to multiple remotes, for one thing. :-)

What about having "git fetch --multiple" without arguments do the same 
thing as "git fetch --all" (possibly renaming skipFetchAll to 
skipFetchDefault)?

Paolo

^ permalink raw reply

* [BUG]
From: Matthieu Moy @ 2009-11-08 20:36 UTC (permalink / raw)
  To: git

[-- Attachment #1: Type: text/plain, Size: 2077 bytes --]

Hi,

I'm hitting a bug when git-push-ing to a Linux PPC machine. In
general, pushing works well, but pushing some particular commits
breaks reproducibly with :

fatal: early EOF
error: unpack failed: unpack-objects abnormal exit
To ssh://localhost//home/perms/moy/prive/dest
 ! [remote rejected] master -> master (n/a (unpacker error))

I've put the guilty files on my website and wrote a reproduction
script:

#!/bin/sh

rm -fr source dest
git init source
git init --bare dest
dest=$PWD/dest
cd source
echo foo > bar.txt
git add .
git commit -m init
git push ssh://localhost/$dest master
wget 'http://www-verimag.imag.fr/~moy/tmp/git-bug/Conception Manual.docx'
wget 'http://www-verimag.imag.fr/~moy/tmp/git-bug/Extreme Programming.doc'
git add .
git commit -m "bug"
git push ssh://localhost/$dest master

The full output is attached (the error message for the last push is
given above). The machine on which I get this (let's call it "A")
says :

$ ssh -Version
OpenSSH_4.3p2, OpenSSL 0.9.8e-fips-rhel5 01 Jul 2008
$ uname -a
Linux A 2.6.18-128.7.1.el5 #1 SMP Wed Aug 19 04:08:13 EDT 2009 ppc64 ppc64 ppc64 GNU/Linux
$ cat /etc/redhat-release                                                                                                                                           
Red Hat Enterprise Linux Server release 5.4 (Tikanga)
(it's a 32-bit distribution although the machine is 64bits)
$ git --version
git version 1.6.5.2
(compiled myself, "make test" passes)

According to my experiments, the problem is on the receiver side. If I
do the same as above, with source/ and dest/ directories on two
different machines, then if source/ in on A and dest/ anywhere else,
it works, and if dest/ is on machine A, I get the same error.

If I push using "file://" instead of "ssh://", then everything works
well.

If instead of push-ing, I go to dest/ and do a fetch, then it works
well too.

Does anyone have any idea on what's going on?

If anyone has a machine similar to mine (ppc64), can he/she run my
reproduction script and tell me if the bug happens?

Thanks a lot,


[-- Attachment #2: git-bug-output.txt --]
[-- Type: text/plain, Size: 4744 bytes --]

Initialized empty Git repository in /perms/moy/prive/source/.git/
Initialized empty Git repository in /perms/moy/prive/dest/
[master (root-commit) e14141d] init
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 bar.txt
Counting objects: 3, done.
Writing objects:  33% (1/3)   \rWriting objects:  66% (2/3)   \rWriting objects: 100% (3/3)   \rWriting objects: 100% (3/3), 209 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To ssh://localhost//home/perms/moy/prive/dest
 * [new branch]      master -> master
--2009-11-08 21:15:27--  http://www-verimag.imag.fr/~moy/tmp/git-bug/Conception%20Manual.docx
Resolving www-verimag.imag.fr... 129.88.43.46
Connecting to www-verimag.imag.fr|129.88.43.46|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1064912 (1.0M) [application/x-zip]
Saving to: `Conception Manual.docx'

     0K .......... .......... .......... .......... ..........  4% 42.9M 0s
    50K .......... .......... .......... .......... ..........  9% 38.1M 0s
   100K .......... .......... .......... .......... .......... 14% 51.4M 0s
   150K .......... .......... .......... .......... .......... 19% 47.1M 0s
   200K .......... .......... .......... .......... .......... 24% 54.5M 0s
   250K .......... .......... .......... .......... .......... 28% 58.4M 0s
   300K .......... .......... .......... .......... .......... 33% 53.5M 0s
   350K .......... .......... .......... .......... .......... 38% 64.5M 0s
   400K .......... .......... .......... .......... .......... 43% 42.0M 0s
   450K .......... .......... .......... .......... .......... 48% 55.7M 0s
   500K .......... .......... .......... .......... .......... 52% 61.9M 0s
   550K .......... .......... .......... .......... .......... 57% 54.4M 0s
   600K .......... .......... .......... .......... .......... 62% 56.3M 0s
   650K .......... .......... .......... .......... .......... 67% 58.8M 0s
   700K .......... .......... .......... .......... .......... 72% 61.6M 0s
   750K .......... .......... .......... .......... .......... 76% 53.5M 0s
   800K .......... .......... .......... .......... .......... 81% 44.3M 0s
   850K .......... .......... .......... .......... .......... 86% 54.4M 0s
   900K .......... .......... .......... .......... .......... 91% 63.9M 0s
   950K .......... .......... .......... .......... .......... 96% 75.0M 0s
  1000K .......... .......... .......... .........            100% 89.8M=0.02s

2009-11-08 21:15:27 (54.1 MB/s) - `Conception Manual.docx' saved [1064912/1064912]

--2009-11-08 21:15:27--  http://www-verimag.imag.fr/~moy/tmp/git-bug/Extreme%20Programming.doc
Resolving www-verimag.imag.fr... 129.88.43.46
Connecting to www-verimag.imag.fr|129.88.43.46|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 521216 (509K) [application/msword]
Saving to: `Extreme Programming.doc'

     0K .......... .......... .......... .......... ..........  9% 42.7M 0s
    50K .......... .......... .......... .......... .......... 19% 38.3M 0s
   100K .......... .......... .......... .......... .......... 29% 51.4M 0s
   150K .......... .......... .......... .......... .......... 39% 48.9M 0s
   200K .......... .......... .......... .......... .......... 49% 51.9M 0s
   250K .......... .......... .......... .......... .......... 58% 57.0M 0s
   300K .......... .......... .......... .......... .......... 68% 54.6M 0s
   350K .......... .......... .......... .......... .......... 78% 56.1M 0s
   400K .......... .......... .......... .......... .......... 88% 52.5M 0s
   450K .......... .......... .......... .......... .......... 98% 75.4M 0s
   500K .........                                             100% 17.6M=0.01s

2009-11-08 21:15:27 (52.3 MB/s) - `Extreme Programming.doc' saved [521216/521216]

[master c0fa75f] bug
 2 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 Conception Manual.docx
 create mode 100644 Extreme Programming.doc
Counting objects: 5, done.
Delta compression using up to 16 threads.
Compressing objects:  25% (1/4)   \rCompressing objects:  50% (2/4)   \rCompressing objects:  75% (3/4)   \rCompressing objects: 100% (4/4)   \rCompressing objects: 100% (4/4), done.
Writing objects:  25% (1/4)   \rWriting objects:  50% (2/4)   \rWriting objects:  75% (3/4)   \rWriting objects: 100% (4/4)   \rWriting objects: 100% (4/4), 1.38 MiB, done.
Total 4 (delta 0), reused 0 (delta 0)
fatal: early EOF
error: unpack failed: unpack-objects abnormal exit
To ssh://localhost//home/perms/moy/prive/dest
 ! [remote rejected] master -> master (n/a (unpacker error))
error: failed to push some refs to 'ssh://localhost//home/perms/moy/prive/dest'

[-- Attachment #3: Type: text/plain, Size: 50 bytes --]


--
Matthieu Moy
http://www-verimag.imag.fr/~moy/

^ permalink raw reply

* Re: Allowing push --dry-run through fetch url
From: Junio C Hamano @ 2009-11-08 19:23 UTC (permalink / raw)
  To: Mike Hommey; +Cc: git
In-Reply-To: <20091106095357.GA13389@glandium.org>

Mike Hommey <mh@glandium.org> writes:

> Usually, when I run git push --dry-run, it's to check that what follows
> (usually the refspec part) does what I want it to do, such as not pushing
> tags I didn't intend to push(*), and stuff like that.

Ahh, that one.

That reminds me of a topic that we discussed but went away without
reaching the conclusion on adding a "confirmation: are you sure this
pushes what you want?" to the command.  I had a doubt about the patch back
then which was that it hardcoded a tty interaction and it would be hard to
retrofit it to help GUI frontends (so my suggestion was to use something
like hooks mechanism, perhaps --confirm=this-script and allow it to do its
GUI thing), but thinking about it again, they can always use "expect" to
drive the interaction with the confirmation prompt, so it may not a big
deal after all---we might want to resurrect the topic.

That was an unrelated, independent thought on your comment, but if we did
so, you might not even have to try to use --dry-run on git:// transport.

^ permalink raw reply

* Re: Automatically remote prune
From: Junio C Hamano @ 2009-11-08 19:08 UTC (permalink / raw)
  To: Petr Baudis; +Cc: Jay Soffian, Junio C Hamano, John Tapsell, Git List
In-Reply-To: <20091106103100.GG17748@machine.or.cz>

Petr Baudis <pasky@suse.cz> writes:

> On Thu, Nov 05, 2009 at 07:38:39PM -0500, Jay Soffian wrote:
>> On Thu, Nov 5, 2009 at 7:17 PM, Petr Baudis <pasky@suse.cz> wrote:
>> > On Thu, Nov 05, 2009 at 06:09:03PM -0500, Jay Soffian wrote:
>> >> Actually, mirror mode applies to push only. Unless I'm missing
>> >> something obvious.
>> >
>> > Perhaps you are, mirror mode applies to fetch as well...

Sorry, my thinko.  We do not do mirrors in fetch.

^ permalink raw reply

* Re: [PATCH] Documentation: avoid tracking intermediate build products
From: Junio C Hamano @ 2009-11-08 19:08 UTC (permalink / raw)
  To: Jonathan Nieder; +Cc: Junio C Hamano, git, Chris Johnsen
In-Reply-To: <20091108112009.GA23790@progeny.tock>

Jonathan Nieder <jrnieder@gmail.com> writes:

> Add *.xml+, *.html+, *.texi+, and *.texi++ to .gitignore.
>
> Cc: Chris Johnsen <chris_johnsen@pobox.com>
> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
> ---
> Some of these files appeared in the "git status" output after an
> interrupted build.  I hope I caught them all.

Thanks; I think "*+" would suffice, though.

^ permalink raw reply

* Re: [gitweb feature request] Release snapshots with vX.X.X tags
From: Junio C Hamano @ 2009-11-08 18:53 UTC (permalink / raw)
  To: Bram Neijt; +Cc: Git mailing list
In-Reply-To: <1257680442.14087.78.camel@owl>

Bram Neijt <bneijt@gmail.com> writes:

> I would like to create release snapshots with a git tag like "v0.0.1".
> For proper Debian packaging, a release snapshot of tag "v0.0.1" would
> have to be named "project-0.0.1.tar.gz" and contain a single directory
> with "project-0.0.1/" in the archive.

What the intended audience of this feature?  IOW,

 - who are going to "click" such a link on gitweb to obtain
   project-0.0.1.tar.gz with project-0.0.1/?

 - how are they going to use that tarball?

I somehow suspect that they won't be the official Debian distro packagers.

Most likely they actually have a clone of the upstream project (how else
they can stay up to date?  In addition they would want to track their own
changes), so it would be more efficient for them to generate such a
tarball from a tag, and more importantly, doing it locally means that they
can they can verify the tag (and the whole history leading to it) before
doing so, instead of relying on somebody else's gitweb.

You could be a mere Debian user who produces a *.deb for his own use out
of such tarball, and in such a case you are a lot less likely be tracking
the project (meaning, reading the history and keeping track of fixed bugs,
new regressions and such) than just getting a snapshot that happens to be
there and building it blindly, and I can understand it would be nicer if
you did not have to unpack, rename and regenerate an archive.

Also, whose gitweb installations are you envisioning to enable this new
feature?  Are you going to convince all the gitweb administrators of
projects packaged by Debian (and derivatives) that have gitweb, and what
are the incentive for these upstream projects to do so?  I would guess
that most of the upstream projects do not consider Debian as their sole
target distribution, and it would be a tough sell if changing the snapshot
name to suit Debian breaks some other distro's (or human users) needs.

Jakub is polishing Mark's patch to change the snapshot name and contents
hierarchy, but I think it won't satisfy Debian's naming guideline (it will
have v0.0.1, not 0.0.1 in the name).  Changing the series's default to
drop 'v' from the beginning of the tagname when the rest of it consists of
all digits and dots would not be a correct solution, as Debian is not the
only system in the world and other people may want different naming rules.

In order to make his series useful for your objective, it probably would
require a bit more customizability, but because I cannot tell whom such a
feature is really trying to help, and what the deployment plans are, I
cannot judge if extra complexity to add such a customizability is worth
it.  Also because there will be conflicts in the desired archive format
("Distro X people want this kind of archive, distro Y people want this
different kind"), the choice somehow how to come from whoever is clicking
the link, not from the gitweb administrator, and it probably would mean
the codepath involved would need a lot more careful audit than just a
server only "this gitweb installation would use this format"
configuration.

^ permalink raw reply

* Re: gitk : french translation
From: Emmanuel Trillaud @ 2009-11-08 17:55 UTC (permalink / raw)
  To: Nicolas Sebrecht; +Cc: Thomas Moulard, Git Mailing List
In-Reply-To: <20091107025439.GC13724@vidovic>

2009/11/7 Nicolas Sebrecht <nicolas.s.dev@gmx.fr>:
> [
>  Please, conform to Documentation/SubmittingPatches of the git.git
>  project and send your patches inline to make the work for reviewers
>  easier.
>
>  Both of your patches lack the Signed-off-by but maybe you don't want
>  them to be merged?
> ]
I am aware of this recommendation but this translation is almost 22kb and
I tought that put it inline wouldn't make the review easier. I will
submit a patch
gathering my workand those of the reviewers soon.

> The 06/11/09, Emmanuel Trillaud wrote:
>
>> > Here is an updated translation with the following changes:
>
> <...>
>
>> > - make some consistency changes
>> >  * s/diff/différences/
>> >  * s/patch/correctif/ everywhere
>
> I disagree here. Words like "diff", "commit", "patch", etc should be
> kept as is. Translation of those terms make things harder for the users.
I agree with you when those terms refers to _commands_ names, but the
main goal of a
translation is to _translate_ and we have to make the best effort to
use french word if they _exist_
and _are_ appropriate (that's why I'm not sure about translate
"cherry-pick" by "ceullir").
I prefer to translate "Diff this -> selected" by "Différence entre ça
et selection"
because it is what the user do when he make a diff. I am also ok to
translate "merge" by "fusion"
because it's what "merge" is in french and I don't this we mislead the
user by using the term
"fusion".

>> > IMHO the most important should be to decide how to translate the git vocabulary.
>> > The Subversion project has guidelines concerning that issue:
>> > http://svn.collab.net/viewvc/svn/trunk/subversion/po/fr.po?revision=39920&view=markup
>> > It may be a good idea to stick with what they are doing if possible.
>
> No, no. SVN and Git vocabulary/operations are not identical (not only
> for 'commit' as you stated). Please, don't make things harder than it
> already is.
Have you read this document? I read it and it contains some
interesting _advices_ in it
(especially for an amateur translator like me) and some translations
ideas. That said, I agree with
your concerns to not make things harder for the user and to choose the
good translations
for the Git vocabulary. I will make a glossary of the Git words and
the proposed translations for them

Cordiallement

Emmanuel

^ permalink raw reply

* [RFC/PATCH] Documentation: add "Fighting regressions with git bisect" article
From: Christian Couder @ 2009-11-08 15:09 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: git, Linus Torvalds, Andreas Ericsson, Ingo Molnar,
	Johannes Schindelin, Jon Seymour, Bill Lear, H Peter Anvin

This patch adds an asciidoc version of the "Fighting regressions with
git bisect" article that the author wrote for the Linux-Kongress
2009 (http://www.linux-kongress.org/2009).

This paper might be interesting to people who want to learn as much as
possible about "git bisect" from a single document.

The slides of the related presentation are available at:

http://www.linux-kongress.org/2009/slides/fighting_regressions_with_git_bisect_christian_couder.pdf

But the Linux Kongress people will not publish this paper online because
they print the papers on their UpTimes magazine
(http://www.lob.de/isbn/978-3-86541-358-1). But they don't take away the
rights of the author (which is very nice), so I have the right to publish
it.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
 Documentation/Makefile              |    1 +
 Documentation/git-bisect-lk2009.txt | 1359 +++++++++++++++++++++++++++++++++++
 Documentation/git-bisect.txt        |    5 +
 3 files changed, 1365 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/git-bisect-lk2009.txt

	Hi,

	Here is the paper that I wrote for the Linux Kongress 2009 in Dresden.
	You can see the PDF version here:

	http://blog.couder.net/public/lk2009-git_bisect.pdf

	As I wanted to have an HTML version of it, I reworked it a little to
	convert it to asciidoc. (In fact I wrote it nearly in asciidoc in the
	first place, but I had to submit it in other formats.)

	It is not only a technical paper, and not only a tutorial either so
	I am not sure where it would be better to add it.

	Thanks again to Junio and Ingo for their help and comments on it,
	Christian.

diff --git a/Documentation/Makefile b/Documentation/Makefile
index cd5b439..3f59952 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -17,6 +17,7 @@ DOC_HTML=$(MAN_HTML)
 ARTICLES = howto-index
 ARTICLES += everyday
 ARTICLES += git-tools
+ARTICLES += git-bisect-lk2009
 # with their own formatting rules.
 SP_ARTICLES = howto/revert-branch-rebase howto/using-merge-subtree user-manual
 API_DOCS = $(patsubst %.txt,%,$(filter-out technical/api-index-skel.txt technical/api-index.txt, $(wildcard technical/api-*.txt)))
diff --git a/Documentation/git-bisect-lk2009.txt b/Documentation/git-bisect-lk2009.txt
new file mode 100644
index 0000000..ca30078
--- /dev/null
+++ b/Documentation/git-bisect-lk2009.txt
@@ -0,0 +1,1359 @@
+Fighting regressions with git bisect
+====================================
+:Author: Christian Couder
+:Email: chriscool@tuxfamily.org
+:Date: 2009/11/08
+
+Abstract
+--------
+
+"git bisect" enables software users and developers to easily find the
+commit that introduced a regression. We show why it is important to
+have good tools to fight regressions. We describe how "git bisect"
+works from the outside and the algorithms it uses inside. Then we
+explain how to take advantage of "git bisect" to improve current
+practices. And we discuss how "git bisect" could improve in the
+future.
+
+
+Introduction to "git bisect"
+----------------------------
+
+Git is a Distributed Version Control system (DVCS) created by Linus
+Torvalds and maintained by Junio Hamano.
+
+In Git like in many other Version Control Systems (VCS), the different
+states of the data that is managed by the system are called
+commits. And, as VCS are mostly used to manage software source code,
+sometimes "interesting" changes of behavior in the software are
+introduced in some commits.
+
+In fact people are specially interested in commits that introduce a
+"bad" behavior, called a bug or a regression. They are interested in
+these commits because a commit (hopefully) contains a very small set
+of source code changes. And it's much easier to understand and
+properly fix a problem when you only need to check a very small set of
+changes, than when you don't know where look in the first place.
+
+So to help people find commits that introduce a "bad" behavior, the
+"git bisect" set of commands was invented. And it follows of course
+that in "git bisect" parlance, commits where the "interesting
+behavior" is present are called "bad" commits, while other commits are
+called "good" commits. And a commit that introduce the behavior we are
+interested in is called a "first bad commit". Note that there could be
+more than one "first bad commit" in the commit space we are searching.
+
+So "git bisect" is designed to help find a "first bad commit". And to
+be as efficient as possible, it tries to perform a binary search.
+
+
+Fighting regressions overview
+-----------------------------
+
+Regressions: a big problem
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Regressions are a big problem in the software industry. But it's
+difficult to put some real numbers behind that claim.
+
+There are some numbers about bugs in general, like a NIST study in
+2002 <<1>> that said:
+
+_____________
+Software bugs, or errors, are so prevalent and so detrimental that
+they cost the U.S. economy an estimated $59.5 billion annually, or
+about 0.6 percent of the gross domestic product, according to a newly
+released study commissioned by the Department of Commerce's National
+Institute of Standards and Technology (NIST). At the national level,
+over half of the costs are borne by software users and the remainder
+by software developers/vendors.  The study also found that, although
+all errors cannot be removed, more than a third of these costs, or an
+estimated $22.2 billion, could be eliminated by an improved testing
+infrastructure that enables earlier and more effective identification
+and removal of software defects. These are the savings associated with
+finding an increased percentage (but not 100 percent) of errors closer
+to the development stages in which they are introduced. Currently,
+over half of all errors are not found until "downstream" in the
+development process or during post-sale software use.
+_____________
+
+And then:
+
+_____________
+Software developers already spend approximately 80 percent of
+development costs on identifying and correcting defects, and yet few
+products of any type other than software are shipped with such high
+levels of errors.
+_____________
+
+Eventually the conclusion started with:
+
+_____________
+The path to higher software quality is significantly improved software
+testing.
+_____________
+
+There are other estimates saying that 80% of the cost related to
+software is about maintenance <<2>>.
+
+Though, according to Wikipedia <<3>>:
+
+_____________
+A common perception of maintenance is that it is merely fixing
+bugs. However, studies and surveys over the years have indicated that
+the majority, over 80%, of the maintenance effort is used for
+non-corrective actions (Pigosky 1997). This perception is perpetuated
+by users submitting problem reports that in reality are functionality
+enhancements to the system.
+_____________
+
+But we can guess that improving on existing software is very costly
+because you have to watch out for regressions. At least this would
+make the above studies consistent among themselves.
+
+Of course some kind of software is developed, then used during some
+time without being improved on much, and then finally thrown away. In
+this case, of course, regressions may not be a big problem. But on the
+other hand, there is a lot of big software that is continually
+developed and maintained during years or even tens of years by a lot
+of people. And as there are often many people who depend (sometimes
+critically) on such software, regressions are a really big problem.
+
+One such software is the linux kernel. And if we look at the linux
+kernel, we can see that a lot of time and effort is spent to fight
+regressions. The release cycle start with a 2 weeks long merge
+window. Then the first release candidate (rc) version is tagged. And
+after that about 7 or 8 more rc versions will appear with around one
+week between each of them, before the final release.
+
+The time between the first rc release and the final release is
+supposed to be used to test rc versions and fight bugs and especially
+regressions. And this time is more than 80% of the release cycle
+time. But this is not the end of the fight yet, as of course it
+continues after the release.
+
+And then this is what Ingo Molnar (a well known linux kernel
+developer) says about his use of git bisect:
+
+_____________
+I most actively use it during the merge window (when a lot of trees
+get merged upstream and when the influx of bugs is the highest) - and
+yes, there have been cases that i used it multiple times a day. My
+average is roughly once a day.
+_____________
+
+So regressions are fought all the time by developers, and indeed it is
+well known that bugs should be fixed as soon as possible, so as soon
+as they are found. That's why it is interesting to have good tools for
+this purpose.
+
+Other tools to fight regressions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+So what are the tools used to fight regressions? They are nearly the
+same as those used to fight regular bugs. The only specific tools are
+test suites and tools similar as "git bisect".
+
+Test suites are very nice. But when they are used alone, they are
+supposed to be used so that all the tests are checked after each
+commit. This means that they are not very efficient, because many
+tests are run for no interesting result, and they suffer from
+combinational explosion.
+
+In fact the problem is that big software often has many different
+configuration options and that each test case should pass for each
+configuration after each commit. So if you have for each release: N
+configurations, M commits and T test cases, you should perform:
+
+-------------
+N * M * T tests
+-------------
+
+where N, M and T are all growing with the size your software.
+
+So very soon it will not be possible to completely test everything.
+
+And if some bugs slip through your test suite, then you can add a test
+to your test suite. But if you want to use your new improved test
+suite to find where the bug slipped in, then you will either have to
+emulate a bisection process or you will perhaps bluntly test each
+commit backward starting from the "bad" commit you have which may be
+very wasteful.
+
+"git bisect" overview
+---------------------
+
+Starting a bisection
+~~~~~~~~~~~~~~~~~~~~
+
+The first "git bisect" subcommand to use is "git bisect start" to
+start the search. Then bounds must be set to limit the commit
+space. This is done usually by giving one "bad" and at least one
+"good" commit. They can be passed in the initial call to "git bisect
+start" like this:
+
+-------------
+$ git bisect start [BAD [GOOD...]]
+-------------
+
+or they can be set using:
+
+-------------
+$ git bisect bad [COMMIT]
+-------------
+
+and:
+
+-------------
+$ git bisect good [COMMIT...]
+-------------
+
+where BAD, GOOD and COMMIT are all names that can be resolved to a
+commit.
+
+Then "git bisect" will checkout a commit of its choosing and ask the
+user to test it, like this:
+
+-------------
+$ git bisect start v2.6.27 v2.6.25
+Bisecting: 10928 revisions left to test after this (roughly 14 steps)
+[2ec65f8b89ea003c27ff7723525a2ee335a2b393] x86: clean up using max_low_pfn on 32-bit
+-------------
+
+Note that the example that we will use is really a toy example, we
+will be looking for the first commit that has a version like
+"2.6.26-something", that is the commit that has a "SUBLEVEL = 26" line
+in the top level Makefile. This is a toy example because there are
+better ways to find this commit with git than using "git bisect" (for
+example "git blame" or "git log -S<string>").
+
+Driving a bisection manually
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+At this point there are basically 2 ways to drive the search. It can
+be driven manually by the user or it can be driven automatically by a
+script or a command.
+
+If the user is driving it, then at each step of the search, the user
+will have to test the current commit and say if it is "good" or "bad"
+using the "git bisect good" or "git bisect bad" commands respectively
+that have been described above. For example:
+
+-------------
+$ git bisect bad
+Bisecting: 5480 revisions left to test after this (roughly 13 steps)
+[66c0b394f08fd89236515c1c84485ea712a157be] KVM: kill file->f_count abuse in kvm
+-------------
+
+And after a few more steps like that, "git bisect" will eventually
+find a first bad commit:
+
+-------------
+$ git bisect bad
+2ddcca36c8bcfa251724fe342c8327451988be0d is the first bad commit
+commit 2ddcca36c8bcfa251724fe342c8327451988be0d
+Author: Linus Torvalds <torvalds@linux-foundation.org>
+Date:   Sat May 3 11:59:44 2008 -0700
+
+    Linux 2.6.26-rc1
+
+:100644 100644 5cf8258195331a4dbdddff08b8d68642638eea57 4492984efc09ab72ff6219a7bc21fb6a957c4cd5 M      Makefile
+-------------
+
+At this point we can see what the commit does, check it out (if it's
+not already checked out) or tinker with it, for example:
+
+-------------
+$ git show HEAD
+commit 2ddcca36c8bcfa251724fe342c8327451988be0d
+Author: Linus Torvalds <torvalds@linux-foundation.org>
+Date:   Sat May 3 11:59:44 2008 -0700
+
+    Linux 2.6.26-rc1
+
+diff --git a/Makefile b/Makefile
+index 5cf8258..4492984 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ VERSION = 2
+ PATCHLEVEL = 6
+-SUBLEVEL = 25
+-EXTRAVERSION =
++SUBLEVEL = 26
++EXTRAVERSION = -rc1
+ NAME = Funky Weasel is Jiggy wit it
+
+ # *DOCUMENTATION*
+-------------
+
+And when we are finished we can use "git bisect reset" to go back to
+the branch we were in before we started bisecting:
+
+-------------
+$ git bisect reset
+Checking out files: 100% (21549/21549), done.
+Previous HEAD position was 2ddcca3... Linux 2.6.26-rc1
+Switched to branch 'master'
+-------------
+
+Driving a bisection automatically
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The other way to drive the bisection process is to tell "git bisect"
+to launch a script or command at each bisection step to know if the
+current commit is "good" or "bad". To do that, we use the "git bisect
+run" command. For example:
+
+-------------
+$ git bisect start v2.6.27 v2.6.25
+Bisecting: 10928 revisions left to test after this (roughly 14 steps)
+[2ec65f8b89ea003c27ff7723525a2ee335a2b393] x86: clean up using max_low_pfn on 32-bit
+$
+$ git bisect run grep '^SUBLEVEL = 25' Makefile
+running grep ^SUBLEVEL = 25 Makefile
+Bisecting: 5480 revisions left to test after this (roughly 13 steps)
+[66c0b394f08fd89236515c1c84485ea712a157be] KVM: kill file->f_count abuse in kvm
+running grep ^SUBLEVEL = 25 Makefile
+SUBLEVEL = 25
+Bisecting: 2740 revisions left to test after this (roughly 12 steps)
+[671294719628f1671faefd4882764886f8ad08cb] V4L/DVB(7879): Adding cx18 Support for mxl5005s
+...
+...
+running grep ^SUBLEVEL = 25 Makefile
+Bisecting: 0 revisions left to test after this (roughly 0 steps)
+[2ddcca36c8bcfa251724fe342c8327451988be0d] Linux 2.6.26-rc1
+running grep ^SUBLEVEL = 25 Makefile
+2ddcca36c8bcfa251724fe342c8327451988be0d is the first bad commit
+commit 2ddcca36c8bcfa251724fe342c8327451988be0d
+Author: Linus Torvalds <torvalds@linux-foundation.org>
+Date:   Sat May 3 11:59:44 2008 -0700
+
+    Linux 2.6.26-rc1
+
+:100644 100644 5cf8258195331a4dbdddff08b8d68642638eea57 4492984efc09ab72ff6219a7bc21fb6a957c4cd5 M      Makefile
+bisect run success
+-------------
+
+In this example, we passed "grep '^SUBLEVEL = 25' Makefile" as
+parameter to "git bisect run". This means that at each step, the grep
+command we passed will be launched. And if it exits with code 0 (that
+means success) then git bisect will mark the current state as
+"good". If it exits with code 1 (or any code between 1 and 127
+included, except the special code 125), then the current state will be
+marked as "bad".
+
+Exit code between 128 and 255 are special to "git bisect run". They
+make it stop immediately the bisection process. This is useful for
+example if the command passed takes too long to complete, because you
+can kill it with a signal and it will stop the bisection process.
+
+It can also be useful in scripts passed to "git bisect run" to "exit
+255" if some very abnormal situation is detected.
+
+Avoiding untestable commits
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Sometimes it happens that the current state cannot be tested, for
+example if it does not compile because there was a bug preventing it
+at that time. This is what the special exit code 125 is for. It tells
+"git bisect run" that the current commit should be marked as
+untestable and that another one should be chosen and checked out.
+
+If the bisection process is driven manually, you can use "git bisect
+skip" to do the same thing. (In fact the special exit code 125 makes
+"git bisect run" use "git bisect skip" in the background.)
+
+Or if you want more control, you can inspect the current state using
+for example "git bisect visualize". It will launch gitk (or "git log"
+if the DISPLAY environment variable is not set) to help you find a
+better bisection point.
+
+Either way, if you have a string of untestable commits, it might
+happen that the regression you are looking for has been introduced by
+one of these untestable commits. In this case it's not possible to
+tell for sure which commit introduced the regression.
+
+So if you used "git bisect skip" (or the run script exited with
+special code 125) you could get a result like this:
+
+-------------
+There are only 'skip'ped commits left to test.
+The first bad commit could be any of:
+15722f2fa328eaba97022898a305ffc8172db6b1
+78e86cf3e850bd755bb71831f42e200626fbd1e0
+e15b73ad3db9b48d7d1ade32f8cd23a751fe0ace
+070eab2303024706f2924822bfec8b9847e4ac1b
+We cannot bisect more!
+-------------
+
+Saving a log and replaying it
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you want to show other people your bisection process, you can get a
+log using for example:
+
+-------------
+$ git bisect log > bisect_log.txt
+-------------
+
+And it is possible to replay it using:
+
+-------------
+$ git bisect replay bisect_log.txt
+-------------
+
+
+"git bisect" details
+--------------------
+
+Bisection algorithm
+~~~~~~~~~~~~~~~~~~~
+
+As the Git commits form a directed acyclic graph (DAG), finding the
+best bisection commit to test at each step is not so simple. Anyway
+Linus found and implemented a "truly stupid" algorithm, later improved
+by Junio Hamano, that works quite well.
+
+So the algorithm used by "git bisect" to find the best bisection
+commit when there are no skipped commits is the following:
+
+1) keep only the commits that:
+
+a) are ancestor of the "bad" commit (including the "bad" commit itself),
+b) are not ancestor of a "good" commit (excluding the "good" commits).
+
+This means that we get rid of the uninteresting commits in the DAG.
+
+For example if we start with a graph like this:
+
+-------------
+G-Y-G-W-W-W-X-X-X-X
+           \ /
+            W-W-B
+           /
+Y---G-W---W
+ \ /   \
+Y-Y     X-X-X-X
+
+-> time goes this way ->
+-------------
+
+where B is the "bad" commit, "G" are "good" commits and W, X, and Y
+are other commits, we will get the following graph after this first
+step:
+
+-------------
+W-W-W
+     \
+      W-W-B
+     /
+W---W
+-------------
+
+So only the W and B commits will be kept. Because commits X and Y will
+have been removed by rules a) and b) respectively, and because commits
+G are removed by rule b) too.
+
+Note for git users, that it is equivalent as keeping only the commit
+given by:
+
+-------------
+git rev-list BAD --not GOOD1 GOOD2...
+-------------
+
+Also note that we don't require the commits that are kept to be
+descendants of a "good" commit. So in the following example, commits W
+and Z will be kept:
+
+-------------
+G-W-W-W-B
+   /
+Z-Z
+-------------
+
+2) starting from the "good" ends of the graph, associate to each
+commit the number of ancestors it has plus one
+
+For example with the following graph where H is the "bad" commit and A
+and D are some parents of some "good" commits:
+
+-------------
+A-B-C
+     \
+      F-G-H
+     /
+D---E
+-------------
+
+this will give:
+
+-------------
+1 2 3
+A-B-C
+     \6 7 8
+      F-G-H
+1   2/
+D---E
+-------------
+
+3) associate to each commit: min(X, N - X)
+
+where X is the value associated to the commit in step 2) and N is the
+total number of commits in the graph.
+
+In the above example we have N = 8, so this will give:
+
+-------------
+1 2 3
+A-B-C
+     \2 1 0
+      F-G-H
+1   2/
+D---E
+-------------
+
+4) the best bisection point is the commit with the highest associated
+number
+
+So in the above example the best bisection point is commit C.
+
+5) note that some shortcuts are implemented to speed up the algorithm
+
+As we know N from the beginning, we know that min(X, N - X) can't be
+greater than N/2. So during steps 2) and 3), if we would associate N/2
+to a commit, then we know this is the best bisection point. So in this
+case we can just stop processing any other commit and return the
+current commit.
+
+Bisection algorithm debugging
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+For any commit graph, you can see the number associated with each
+commit using "git rev-list --bisect-all".
+
+For example, for the above graph, a command like:
+
+-------------
+$ git rev-list --bisect-all BAD --not GOOD1 GOOD2
+-------------
+
+would output something like:
+
+-------------
+e15b73ad3db9b48d7d1ade32f8cd23a751fe0ace (dist=3)
+15722f2fa328eaba97022898a305ffc8172db6b1 (dist=2)
+78e86cf3e850bd755bb71831f42e200626fbd1e0 (dist=2)
+a1939d9a142de972094af4dde9a544e577ddef0e (dist=2)
+070eab2303024706f2924822bfec8b9847e4ac1b (dist=1)
+a3864d4f32a3bf5ed177ddef598490a08760b70d (dist=1)
+a41baa717dd74f1180abf55e9341bc7a0bb9d556 (dist=1)
+9e622a6dad403b71c40979743bb9d5be17b16bd6 (dist=0)
+-------------
+
+Bisection algorithm discussed
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+First let's define "best bisection point". We will say that a commit X
+is a best bisection point or a best bisection commit if knowing its
+state ("good" or "bad") gives as much information as possible whether
+the state of the commit happens to be "good" or "bad".
+
+This means that the best bisection commits are the commits where the
+following function is maximum:
+
+-------------
+f(X) = min(information_if_good(X), information_if_bad(X))
+-------------
+
+where information_if_good(X) is the information we get if X is good
+and information_if_bad(X) is the information we get if X is bad.
+
+Now we will suppose that there is only one "first bad commit". This
+means that all its descendants are "bad" and all the other commits are
+"good". And we will suppose that all commits have an equal probability
+of being good or bad, or of being the first bad commit, so knowing the
+state of c commits gives always the same amount of information
+wherever these c commits are on the graph and whatever c is. (So we
+suppose that these commits being for example on a branch or near a
+good or a bad commit does not give more or less information).
+
+Let's also suppose that we have a cleaned up graph like one after step
+1) in the bisection algorithm above. This means that we can measure
+the information we get in terms of number of commit we can remove from
+the graph..
+
+And let's take a commit X in the graph.
+
+If X is found to be "good", then we know that its ancestors are all
+"good", so we want to say that:
+
+-------------
+information_if_good(X) = number_of_ancestors(X)  (TRUE)
+-------------
+
+And this is true because at step 1) b) we remove the ancestors of the
+"good" commits.
+
+If X is found to be "bad", then we know that its descendants are all
+"bad", so we want to say that:
+
+-------------
+information_if_bad(X) = number_of_descendants(X)  (WRONG)
+-------------
+
+But this is wrong because at step 1) a) we keep only the ancestors of
+the bad commit. So we get more information when a commit is marked as
+"bad", because we also know that the ancestors of the previous "bad"
+commit that are not ancestors of the new "bad" commit are not the
+first bad commit. We don't know if they are good or bad, but we know
+that they are not the first bad commit because they are not ancestor
+of the new "bad" commit.
+
+So when a commit is marked as "bad" we know we can remove all the
+commits in the graph except those that are ancestors of the new "bad"
+commit. This means that:
+
+-------------
+information_if_bad(X) = N - number_of_ancestors(X)  (TRUE)
+-------------
+
+where N is the number of commits in the (cleaned up) graph.
+
+So in the end this means that to find the best bisection commits we
+should maximize the function:
+
+-------------
+f(X) = min(number_of_ancestors(X), N - number_of_ancestors(X))
+-------------
+
+And this is nice because at step 2) we compute number_of_ancestors(X)
+and so at step 3) we compute f(X).
+
+Let's take the following graph as an example:
+
+-------------
+            G-H-I-J
+           /       \
+A-B-C-D-E-F         O
+           \       /
+            K-L-M-N
+-------------
+
+If we compute the following non optimal function on it:
+
+-------------
+g(X) = min(number_of_ancestors(X), number_of_descendants(X))
+-------------
+
+we get:
+
+-------------
+            4 3 2 1
+            G-H-I-J
+1 2 3 4 5 6/       \0
+A-B-C-D-E-F         O
+           \       /
+            K-L-M-N
+            4 3 2 1
+-------------
+
+but with the algorithm used by git bisect we get:
+
+-------------
+            7 7 6 5
+            G-H-I-J
+1 2 3 4 5 6/       \0
+A-B-C-D-E-F         O
+           \       /
+            K-L-M-N
+            7 7 6 5
+-------------
+
+So we chose G, H, K or L as the best bisection point, which is better
+than F. Because if for example L is bad, then we will know not only
+that L, M and N are bad but also that G, H, I and J are not the first
+bad commit (since we suppose that there is only one first bad commit
+and it must be an ancestor of L).
+
+So the current algorithm seems to be the best possible given what we
+initially supposed.
+
+Skip algorithm
+~~~~~~~~~~~~~~
+
+When some commits have been skipped (using "git bisect skip"), then
+the bisection algorithm is the same for step 1) to 3). But then we use
+roughly the following steps:
+
+6) sort the commit by decreasing associated value
+
+7) if the first commit has not been skipped, we can return it and stop
+here
+
+8) otherwise filter out all the skipped commits in the sorted list
+
+9) use a pseudo random number generator (PRNG) to generate a random
+number between 0 and 1
+
+10) multiply this random number with its square root to bias it toward
+0
+
+11) multiply the result by the number of commits in the filtered list
+to get an index into this list
+
+12) return the commit at the computed index
+
+Skip algorithm discussed
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+After step 7) (in the skip algorithm), we could check if the second
+commit has been skipped and return it if it is not the case. And in
+fact that was the algorithm we used from when "git bisect skip" was
+developed in git version 1.5.4 (released on February 1st 2008) until
+git version 1.6.4 (released July 29th 2009).
+
+But Ingo Molnar and H. Peter Anvin (another well known linux kernel
+developer) both complained that sometimes the best bisection points
+all happened to be in an area where all the commits are
+untestable. And in this case the user was asked to test many
+untestable commits, which could be very inefficient.
+
+Indeed untestable commits are often untestable because a breakage was
+introduced at one time, and that breakage was fixed only after many
+other commits were introduced.
+
+This breakage is of course most of the time unrelated to the breakage
+we are trying to locate in the commit graph. But it prevents us to
+know if the interesting "bad behavior" is present or not.
+
+So it is a fact that commits near an untestable commit have a high
+probability of being untestable themselves. And the best bisection
+commits are often found together too (due to the bisection algorithm).
+
+This is why it is a bad idea to just chose the next best unskipped
+bisection commit when the first one has been skipped.
+
+We found that most commits on the graph may give quite a lot of
+information when they are tested. And the commits that will not on
+average give a lot of information are the one near the good and bad
+commits.
+
+So using a PRNG with a bias to favor commits away from the good and
+bad commits looked like a good choice.
+
+One obvious improvement to this algorithm would be to look for a
+commit that has an associated value near the one of the best bisection
+commit, and that is on another branch, before using the PRNG. Because
+if such a commit exists, then it is not very likely to be untestable
+too, so it will probably give more information than a nearly randomly
+chosen one.
+
+Checking merge bases
+~~~~~~~~~~~~~~~~~~~~
+
+There is another tweak in the bisection algorithm that has not been
+described in the "bisection algorithm" above.
+
+We supposed in the previous examples that the "good" commits were
+ancestors of the "bad" commit. But this is not a requirement of "git
+bisect".
+
+Of course the "bad" commit cannot be an ancestor of a "good" commit,
+because the ancestors of the good commits are supposed to be
+"good". And all the "good" commits must be related to the bad commit.
+They cannot be on a branch that has no link with the branch of the
+"bad" commit. But it is possible for a good commit to be related to a
+bad commit and yet not be neither one of its ancestor nor one of its
+descendants.
+
+For example, there can be a "main" branch, and a "dev" branch that was
+forked of the main branch at a commit named "D" like this:
+
+-------------
+A-B-C-D-E-F-G  <--main
+       \
+        H-I-J  <--dev
+-------------
+
+The commit "D" is called a "merge base" for branch "main" and "dev"
+because it's the best common ancestor for these branches for a merge.
+
+Now let's suppose that commit J is bad and commit G is good and that
+we apply the bisection algorithm like it has been previously
+described.
+
+As described in step 1) b) of the bisection algorithm, we remove all
+the ancestors of the good commits because they are supposed to be good
+too.
+
+So we would be left with only:
+
+-------------
+H-I-J
+-------------
+
+But what happens if the first bad commit is "B" and if it has been
+fixed in the "main" branch by commit "F"?
+
+The result of such a bisection would be that we would find that H is
+the first bad commit, when in fact it's B. So that would be wrong!
+
+And yes it's can happen in practice that people working on one branch
+are not aware that people working on another branch fixed a bug! It
+could also happen that F fixed more than one bug or that it is a
+revert of some big development effort that was not ready to be
+released.
+
+In fact development teams often maintain both a development branch and
+a maintenance branch, and it would be quite easy for them if "git
+bisect" just worked when they want to bisect a regression on the
+development branch that is not on the maintenance branch. They should
+be able to start bisecting using:
+
+-------------
+$ git bisect start dev main
+-------------
+
+To enable that additional nice feature, when a bisection is started
+and when some good commits are not ancestors of the bad commit, we
+first compute the merge bases between the bad and the good commits and
+we chose these merge bases as the first commits that will be checked
+out and tested.
+
+If it happens that one merge base is bad, then the bisection process
+is stopped with a message like:
+
+-------------
+The merge base BBBBBB is bad.
+This means the bug has been fixed between BBBBBB and [GGGGGG,...].
+-------------
+
+where BBBBBB is the sha1 hash of the bad merge base and [GGGGGG,...]
+is a comma separated list of the sha1 of the good commits.
+
+If some of the merge bases are skipped, then the bisection process
+continues, but the following message is printed for each skipped merge
+base:
+
+-------------
+Warning: the merge base between BBBBBB and [GGGGGG,...] must be skipped.
+So we cannot be sure the first bad commit is between MMMMMM and BBBBBB.
+We continue anyway.
+-------------
+
+where BBBBBB is the sha1 hash of the bad commit, MMMMMM is the sha1
+hash of the merge base that is skipped and [GGGGGG,...]  is a comma
+separated list of the sha1 of the good commits.
+
+So if there is no bad merge base, the bisection process continues as
+usual after this step.
+
+Best bisecting practices
+------------------------
+
+Using test suites and git bisect together
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you both have a test suite and use git bisect, then it becomes less
+important to check that all tests pass after each commit. Though of
+course it is probably a good idea to have some checks to avoid
+breaking too many things because it could make bisecting other bugs
+more difficult.
+
+You can focus your efforts to check at a few points (for example rc
+and beta releases) that all the T test cases pass for all the N
+configurations. And when some tests don't pass you can use "git
+bisect" (or better "git bisect run"). So you should perform roughly:
+
+-------------
+c * N * T + b * M * log2(M) tests
+-------------
+
+where c is the number of rounds of test (so a small constant) and b is
+the ratio of bug per commit (hopefully a small constant too).
+
+So of course it's much better as it's O(N \* T) vs O(N \* T \* M) if
+you would test everything after each commit.
+
+This means that test suites are good to prevent some bugs from being
+committed and they are also quite good to tell you that you have some
+bugs. But they are not so good to tell you where some bugs have been
+introduced. To tell you that efficiently, git bisect is needed.
+
+The other nice thing with test suites, is that when you have one, you
+already know how to test for bad behavior. So you can use this
+knowledge to create a new test case for "git bisect" when it appears
+that there is a regression. So it will be easier to bisect the bug and
+fix it. And then you can add the test case you just created to your
+test suite.
+
+So if you know how to create test cases and how to bisect, you will be
+subject to a virtuous circle:
+
+more tests => easier to create tests => easier to bisect => more tests
+
+So test suites and "git bisect" are complementary tools that are very
+powerful and efficient when used together.
+
+Bisecting build failures
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can very easily automatically bisect broken builds using something
+like:
+
+-------------
+$ git bisect start BAD GOOD
+$ git bisect run make
+-------------
+
+Passing sh -c "some commands" to "git bisect run"
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+For example:
+
+-------------
+$ git bisect run sh -c "make || exit 125; ./my_app | grep 'good output'"
+-------------
+
+On the other hand if you do this often, then it can be worth having
+scripts to avoid too much typing.
+
+Finding performance regressions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here is an example script that comes slightly modified from a real
+world script used by Junio Hamano <<4>>.
+
+This script can be passed to "git bisect run" to find the commit that
+introduced a performance regression:
+
+-------------
+#!/bin/sh
+
+# Build errors are not what I am interested in.
+make my_app || exit 255
+
+# We are checking if it stops in a reasonable amount of time, so
+# let it run in the background...
+
+./my_app >log 2>&1 &
+
+# ... and grab its process ID.
+pid=$!
+
+# ... and then wait for sufficiently long.
+sleep $NORMAL_TIME
+
+# ... and then see if the process is still there.
+if kill -0 $pid
+then
+	# It is still running -- that is bad.
+	kill $pid; sleep 1; kill $pid;
+	exit 1
+else
+	# It has already finished (the $pid process was no more),
+        # and we are happy.
+	exit 0
+fi
+-------------
+
+Following general best practices
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+It is obviously a good idea not to have commits with changes that
+knowingly break things, even if some other commits later fix the
+breakage.
+
+It is also a good idea when using any VCS to have only one small
+logical change in each commit.
+
+The smaller the changes in your commit, the most effective "git
+bisect" will be. And you will probably need "git bisect" less in the
+first place, as small changes are easier to review even if they are
+only reviewed by the commiter.
+
+Another good idea is to have good commit messages. They can be very
+helpful to understand why some changes were made.
+
+These general best practices are very helpful if you bisect often.
+
+Avoiding bug prone merges
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+First merges by themselves can introduce some regressions even when
+the merge needs no source code conflict resolution. This is because a
+semantic change can happen in one branch while the other branch is not
+aware of it.
+
+For example one branch can change the semantic of a function while the
+other branch add more calls to the same function.
+
+This is made much worse if many files have to be fixed to resolve
+conflicts. That's why such merges are called "evil merges". They can
+make regressions very difficult to track down. It can even be
+misleading to know the first bad commit if it happens to be such a
+merge, because people might think that the bug comes from bad conflict
+resolution when it comes from a semantic change in one branch.
+
+Anyway "git rebase" can be used to linearize history. This can be used
+either to avoid merging in the first place. Or it can be used to
+bisect on a linear history instead of the non linear one, as this
+should give more information in case of a semantic change in one
+branch.
+
+Merges can be also made simpler by using smaller branches or by using
+many topic branches instead of only long version related branches.
+
+And testing can be done more often in special integration branches
+like linux-next for the linux kernel.
+
+Adapting your work-flow
+~~~~~~~~~~~~~~~~~~~~~~~
+
+A special work-flow to process regressions can give great results.
+
+Here is an example of a work-flow used by Andreas Ericsson:
+
+* write, in the test suite, a test script that exposes the regression
+* use "git bisect run" to find the commit that introduced it
+* fix the bug that is often made obvious by the previous step
+* commit both the fix and the test script (and if needed more tests)
+
+And here is what Andreas said about this work-flow <<5>>:
+
+_____________
+To give some hard figures, we used to have an average report-to-fix
+cycle of 142.6 hours (according to our somewhat weird bug-tracker
+which just measures wall-clock time). Since we moved to git, we've
+lowered that to 16.2 hours. Primarily because we can stay on top of
+the bug fixing now, and because everyone's jockeying to get to fix
+bugs (we're quite proud of how lazy we are to let git find the bugs
+for us). Each new release results in ~40% fewer bugs (almost certainly
+due to how we now feel about writing tests).
+_____________
+
+Clearly this work-flow uses the virtuous circle between test suites
+and "git bisect". In fact it makes it the standard procedure to deal
+with regression.
+
+In other messages Andreas says that they also use the "best practices"
+described above: small logical commits, topic branches, no evil
+merge,... These practices all improve the bisectability of the commit
+graph, by making it easier and more useful to bisect.
+
+So a good work-flow should be designed around the above points. That
+is making bisecting easier, more useful and standard.
+
+Involving QA people and if possible end users
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+One nice about "git bisect" is that it is not only a developer
+tool. It can effectively be used by QA people or even end users (if
+they have access to the source code or if they can get access to all
+the builds).
+
+There was a discussion at one point on the linux kernel mailing list
+of whether it was ok to always ask end user to bisect, and very good
+points were made to support the point of view that it is ok.
+
+For example David Miller wrote <<6>>:
+
+_____________
+What people don't get is that this is a situation where the "end node
+principle" applies. When you have limited resources (here: developers)
+you don't push the bulk of the burden upon them. Instead you push
+things out to the resource you have a lot of, the end nodes (here:
+users), so that the situation actually scales.
+_____________
+
+This means that it is often "cheaper" if QA people or end users can do
+it.
+
+What is interesting too is that end users that are reporting bugs (or
+QA people that reproduced a bug) have access to the environment where
+the bug happens. So they can often more easily reproduce a
+regression. And if they can bisect, then more information will be
+extracted from the environment where the bug happens, which means that
+it will be easier to understand and then fix the bug.
+
+For open source projects it can be a good way to get more useful
+contributions from end users, and to introduce them to QA and
+development activities.
+
+Using complex scripts
+~~~~~~~~~~~~~~~~~~~~~
+
+In some cases like for kernel development it can be worth developing
+complex scripts to be able to fully automate bisecting.
+
+Here is what Ingo Molnar says about that <<7>>:
+
+_____________
+i have a fully automated bootup-hang bisection script. It is based on
+"git-bisect run". I run the script, it builds and boots kernels fully
+automatically, and when the bootup fails (the script notices that via
+the serial log, which it continuously watches - or via a timeout, if
+the system does not come up within 10 minutes it's a "bad" kernel),
+the script raises my attention via a beep and i power cycle the test
+box. (yeah, i should make use of a managed power outlet to 100%
+automate it)
+_____________
+
+Combining test suites, git bisect and other systems together
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+We have seen that test suites an git bisect are very powerful when
+used together. It can be even more powerful if you can combine them
+with other systems.
+
+For example some test suites could be run automatically at night with
+some unusual (or even random) configurations. And if a regression is
+found by a test suite, then "git bisect" can be automatically
+launched, and its result can be emailed to the author of the first bad
+commit found by "git bisect", and perhaps other people too. And a new
+entry in the bug tracking system could be automatically created too.
+
+
+The future of bisecting
+-----------------------
+
+"git replace"
+~~~~~~~~~~~~~
+
+We saw earlier that "git bisect skip" is now using a PRNG to try to
+avoid areas in the commit graph where commits are untestable. The
+problem is that sometimes the first bad commit will be in an
+untestable area.
+
+To simplify the discussion we will suppose that the untestable area is
+a simple string of commits and that it was created by a breakage
+introduced by one commit (let's call it BBC for bisect breaking
+commit) and later fixed by another one (let's call it BFC for bisect
+fixing commit).
+
+For example:
+
+-------------
+...-Y-BBC-X1-X2-X3-X4-X5-X6-BFC-Z-...
+-------------
+
+where we know that Y is good and BFC is bad, and where BBC and X1 to
+X6 are untestable.
+
+In this case if you are bisecting manually, what you can do is create
+a special branch that starts just before the BBC. The first commit in
+this branch should be the BBC with the BFC squashed into it. And the
+other commits in the branch should be the commits between BBC and BFC
+rebased on the first commit of the branch and then the commit after
+BFC also rebased on.
+
+For example:
+
+-------------
+      (BBC+BFC)-X1'-X2'-X3'-X4'-X5'-X6'-Z'
+     /
+...-Y-BBC-X1-X2-X3-X4-X5-X6-BFC-Z-...
+-------------
+
+where commits quoted with ' have been rebased.
+
+You can easily create such a branch with Git using interactive rebase.
+
+For example using:
+
+-------------
+$ git rebase -i Y Z
+-------------
+
+and then moving BFC after BBC and squashing it.
+
+After that you can start bisecting as usual in the new branch and you
+should eventually find the first bad commit.
+
+For example:
+
+-------------
+$ git bisect start Z' Y
+-------------
+
+If you are using "git bisect run", you can use the same manual fix up
+as above, and then start another "git bisect run" in the special
+branch. Or as the "git bisect" man page says, the script passed to
+"git bisect run" can apply a patch before it compiles and test the
+software <<8>>. The patch should turn a current untestable commits
+into a testable one. So the testing will result in "good" or "bad" and
+"git bisect" will be able to find the first bad commit. And the script
+should not forget to remove the patch once the testing is done before
+exiting from the script.
+
+(Note that instead of a patch you can use "git cherry-pick BFC" to
+apply the fix, and in this case you should use "git reset --hard
+HEAD^" to revert the cherry-pick after testing and before returning
+from the script.)
+
+But the above ways to work around untestable areas are a little bit
+clunky. Using special branches is nice because these branches can be
+shared by developers like usual branches, but the risk is that people
+will get many such branches. And it disrupts the normal "git bisect"
+work-flow. So, if you want to use "git bisect run" completely
+automatically, you have to add special code in your script to restart
+bisection in the special branches.
+
+Anyway one can notice in the above special branch example that the Z'
+and Z commits should point to the same source code state (the same
+"tree" in git parlance). That's because Z' result from applying the
+same changes as Z just in a slightly different order.
+
+So if we could just "replace" Z by Z' when we bisect, then we would
+not need to add anything to a script. It would just work for anyone in
+the project sharing the special branches and the replacements.
+
+With the example above that would give:
+
+-------------
+      (BBC+BFC)-X1'-X2'-X3'-X4'-X5'-X6'-Z'-...
+     /
+...-Y-BBC-X1-X2-X3-X4-X5-X6-BFC-Z
+-------------
+
+That's why the "git replace" command was created. Technically it
+stores replacements "refs" in the "refs/replace/" hierarchy. These
+"refs" are like branches (that are stored in "refs/heads/") or tags
+(that are stored in "refs/tags"), and that means that they can
+automatically be shared like branches or tags among developers.
+
+"git replace" is a very powerful mechanism. It can be used to fix
+commits in already released history, for example to change the commit
+message or the author. And it can also be used instead of git "grafts"
+to link a repository with another old repository.
+
+In fact it's this last feature that "sold" it to the git community, so
+it is now in the "master" branch of git's git repository and it should
+be released in git 1.6.5 in October or November 2009.
+
+One problem with "git replace" is that currently it stores all the
+replacements refs in "refs/replace/", but it would be perhaps better
+if the replacement refs that are useful only for bisecting would be in
+"refs/replace/bisect/". This way the replacement refs could be used
+only for bisecting, while other refs directly in "refs/replace/" would
+be used nearly all the time.
+
+Bisecting sporadic bugs
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Another possible improvement to "git bisect" would be to optionally
+add some redundancy to the tests performed so that it would be more
+reliable when tracking sporadic bugs.
+
+This has been requested by some kernel developers because some bugs
+called sporadic bugs do not appear in all the kernel builds because
+they are very dependent on the compiler output.
+
+The idea is that every 3 test for example, "git bisect" could ask the
+user to test a commit that has already been found to be "good" or
+"bad" (because one of its descendants or one of its ancestors has been
+found to be "good" or "bad" respectively). If it happens that a commit
+has been previously incorrectly classified then the bisection can be
+aborted early, hopefully before too many mistakes have been made. Then
+the user will have to look at what happened and then restart the
+bisection using a fixed bisect log.
+
+There is already a project called BBChop created by Ealdwulf Wuffinga
+on Github that does something like that using Bayesian Search Theory
+<<9>>:
+
+_____________
+BBChop is like 'git bisect' (or equivalent), but works when your bug
+is intermittent. That is, it works in the presence of false negatives
+(when a version happens to work this time even though it contains the
+bug). It assumes that there are no false positives (in principle, the
+same approach would work, but adding it may be non-trivial).
+_____________
+
+But BBChop is independent of any VCS and it would be easier for Git
+users to have something integrated in Git.
+
+Conclusion
+----------
+
+We have seen that regressions are an important problem, and that "git
+bisect" has nice features that complement very well practices and
+other tools, especially test suites, that are generally used to fight
+regressions. But it might be needed to change some work-flows and
+(bad) habits to get the most out of it.
+
+Some improvements to the algorithms inside "git bisect" are possible
+and some new features could help in some cases, but overall "git
+bisect" works already very well, is used a lot, and is already very
+useful. To back up that last claim, let's give the final word to Ingo
+Molnar when he was asked by the author how much time does he think
+"git bisect" saves him when he uses it:
+
+_____________
+a _lot_.
+
+About ten years ago did i do my first 'bisection' of a Linux patch
+queue. That was prior the Git (and even prior the BitKeeper) days. I
+literally days spent sorting out patches, creating what in essence
+were standalone commits that i guessed to be related to that bug.
+
+It was a tool of absolute last resort. I'd rather spend days looking
+at printk output than do a manual 'patch bisection'.
+
+With Git bisect it's a breeze: in the best case i can get a ~15 step
+kernel bisection done in 20-30 minutes, in an automated way. Even with
+manual help or when bisecting multiple, overlapping bugs, it's rarely
+more than an hour.
+
+In fact it's invaluable because there are bugs i would never even
+_try_ to debug if it wasn't for git bisect. In the past there were bug
+patterns that were immediately hopeless for me to debug - at best i
+could send the crash/bug signature to lkml and hope that someone else
+can think of something.
+
+And even if a bisection fails today it tells us something valuable
+about the bug: that it's non-deterministic - timing or kernel image
+layout dependent.
+
+So git bisect is unconditional goodness - and feel free to quote that 
+;-)
+_____________
+
+Acknowledgements
+----------------
+
+Many thanks to Junio Hamano for his help in reviewing this paper, for
+reviewing the patches I sent to the git mailing list, for discussing
+some ideas and helping me improve them, for improving "git bisect" a
+lot and for his awesome work in maintaining and developing Git.
+
+Many thanks to Ingo Molnar for giving me very useful information that
+appears in this paper, for commenting on this paper, for his
+suggestions to improve "git bisect" and for evangelizing "git bisect"
+on the linux kernel mailing lists.
+
+Many thanks to Linus Torvalds for inventing, developing and
+evangelizing "git bisect", Git and Linux.
+
+Many thanks to the many other great people who helped one way or
+another when I worked on git, especially to Andreas Ericsson, Johannes
+Schindelin, H. Peter Anvin, Daniel Barkalow, Bill Lear, John Hawley,
+Shawn O. Pierce, Jeff King, Sam Vilain, Jon Seymour.
+
+Many thanks to the Linux-Kongress program committee for choosing the
+author to given a talk and for publishing this paper.
+
+References
+----------
+
+- [[[1]]] http://www.nist.gov/public_affairs/releases/n02-10.htm['Software Errors Cost U.S. Economy $59.5 Billion Annually'. Nist News Release.]
+- [[[2]]] http://java.sun.com/docs/codeconv/html/CodeConventions.doc.html#16712['Code Conventions for the Java Programming Language'. Sun Microsystems.]
+- [[[3]]] http://en.wikipedia.org/wiki/Software_maintenance['Software maintenance'. Wikipedia.]
+- [[[4]]] http://article.gmane.org/gmane.comp.version-control.git/45195/[Junio C Hamano. 'Automated bisect success story'. Gmane.]
+- [[[5]]] http://lwn.net/Articles/317154/[Christian Couder. 'Fully automated bisecting with "git bisect run"'. LWN.net.]
+- [[[6]]] http://lwn.net/Articles/277872/[Jonathan Corbet. 'Bisection divides users and developers'. LWN.net.]
+- [[[7]]] http://article.gmane.org/gmane.linux.scsi/36652/[Ingo Molnar. 'Re: BUG 2.6.23-rc3 can't see sd partitions on Alpha'. Gmane.]
+- [[[8]]] http://www.kernel.org/pub/software/scm/git/docs/git-bisect.html[Junio C Hamano and the git-list. 'git-bisect(1) Manual Page'. Linux Kernel Archives.]
+- [[[9]]] http://github.com/Ealdwulf/bbchop[Ealdwulf. 'bbchop'. GitHub.]
+
diff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.txt
index d2ffae0..c39d957 100644
--- a/Documentation/git-bisect.txt
+++ b/Documentation/git-bisect.txt
@@ -330,6 +330,11 @@ Documentation
 -------------
 Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.
 
+SEE ALSO
+--------
+link:git-bisect-lk2009.html[Fighting regressions with git bisect],
+linkgit:git-blame[1].
+
 GIT
 ---
 Part of the linkgit:git[1] suite
-- 
1.6.5.1.gaf97d

^ permalink raw reply related

* [RFC/PATCH 4/4] Re-implement 'git remote update' using 'git fetch'
From: Björn Gustavsson @ 2009-11-08 15:48 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano

In order to not duplicate functionality, re-implement 'git remote
update' in terms of 'git fetch'.

There is one incompatibility: the skipDefaultUpdate configuration
variable will only be honored if remotes.default is not set (i.e.
when 'git remote update' will invoke 'git fetch --all', not when
it will invoke 'git fetch default').

Signed-off-by: Björn Gustavsson <bgustavsson@gmail.com>
---
 builtin-remote.c |   86 ++++++++++++++++-------------------------------------
 1 files changed, 26 insertions(+), 60 deletions(-)

diff --git a/builtin-remote.c b/builtin-remote.c
index 0777dd7..fd7e0b2 100644
--- a/builtin-remote.c
+++ b/builtin-remote.c
@@ -1189,88 +1189,54 @@ static int prune_remote(const char *remote, int dry_run)
 	return result;
 }
 
-static int get_one_remote_for_update(struct remote *remote, void *priv)
+static int get_remote_default(const char *key, const char *value, void *priv)
 {
-	struct string_list *list = priv;
-	if (!remote->skip_default_update)
-		string_list_append(remote->name, list);
-	return 0;
-}
-
-static struct remote_group {
-	const char *name;
-	struct string_list *list;
-} remote_group;
-
-static int get_remote_group(const char *key, const char *value, void *num_hits)
-{
-	if (!prefixcmp(key, "remotes.") &&
-			!strcmp(key + 8, remote_group.name)) {
-		/* split list by white space */
-		int space = strcspn(value, " \t\n");
-		while (*value) {
-			if (space > 1) {
-				string_list_append(xstrndup(value, space),
-						remote_group.list);
-				++*((int *)num_hits);
-			}
-			value += space + (value[space] != '\0');
-			space = strcspn(value, " \t\n");
-		}
+	if (strcmp(key, "remotes.default") == 0) {
+		int *found = priv;
+		*found = 1;
 	}
-
 	return 0;
 }
 
 static int update(int argc, const char **argv)
 {
-	int i, result = 0, prune = 0;
-	struct string_list list = { NULL, 0, 0, 0 };
-	static const char *default_argv[] = { NULL, "default", NULL };
+	int i, prune = 0;
 	struct option options[] = {
 		OPT_GROUP("update specific options"),
 		OPT_BOOLEAN('p', "prune", &prune,
 			    "prune remotes after fetching"),
 		OPT_END()
 	};
+	const char **fetch_argv;
+	int fetch_argc = 0;
+	int default_defined = 0;
+
+	fetch_argv = xmalloc(sizeof(char *) * (argc+4));
 
 	argc = parse_options(argc, argv, NULL, options, builtin_remote_usage,
 			     PARSE_OPT_KEEP_ARGV0);
-	if (argc < 2) {
-		argc = 2;
-		argv = default_argv;
-	}
 
-	remote_group.list = &list;
-	for (i = 1; i < argc; i++) {
-		int groups_found = 0;
-		remote_group.name = argv[i];
-		result = git_config(get_remote_group, &groups_found);
-		if (!groups_found && (i != 1 || strcmp(argv[1], "default"))) {
-			struct remote *remote;
-			if (!remote_is_configured(argv[i]))
-				die("No such remote or remote group: %s",
-				    argv[i]);
-			remote = remote_get(argv[i]);
-			string_list_append(remote->name, remote_group.list);
-		}
-	}
+	fetch_argv[fetch_argc++] = "fetch";
 
-	if (!result && !list.nr  && argc == 2 && !strcmp(argv[1], "default"))
-		result = for_each_remote(get_one_remote_for_update, &list);
+	if (verbose)
+		fetch_argv[fetch_argc++] = "-v";
+	if (argc < 2) {
+		fetch_argv[fetch_argc++] = "default";
+	} else {
+		fetch_argv[fetch_argc++] = "--multiple";
+		for (i = 1; i < argc; i++)
+			fetch_argv[fetch_argc++] = argv[i];
+	}
 
-	for (i = 0; i < list.nr; i++) {
-		int err = fetch_remote(list.items[i].string);
-		result |= err;
-		if (!err && prune)
-			result |= prune_remote(list.items[i].string, 0);
+	if (strcmp(fetch_argv[fetch_argc-1], "default") == 0) {
+		git_config(get_remote_default, &default_defined);
+		if (!default_defined)
+			fetch_argv[fetch_argc-1] = "--all";
 	}
 
-	/* all names were strdup()ed or strndup()ed */
-	list.strdup_strings = 1;
-	string_list_clear(&list, 0);
+	fetch_argv[fetch_argc] = NULL;
 
-	return result;
+	return run_command_v_opt(fetch_argv, RUN_GIT_CMD);
 }
 
 static int get_one_entry(struct remote *remote, void *priv)
-- 
1.6.5.1.69.g36942

^ permalink raw reply related

* [RFC/PATCH 3/4] Add the configure variable skipFetchAll
From: Björn Gustavsson @ 2009-11-08 15:47 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano

Implement the configure skipFetchAll variable to allow
certain remotes to be skipped when doing 'git fetch --all' and
'git remote update'. The existing skipDefaultUpdate variable
is still honored (by 'git fetch --all' and 'git remote update').
(If both are set in the configuration file with different values,
the value of the last occurrence will be used.)

Signed-off-by: Björn Gustavsson <bgustavsson@gmail.com>
---
 builtin-fetch.c |    3 ++-
 remote.c        |    3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/builtin-fetch.c b/builtin-fetch.c
index 7926658..651e9c3 100644
--- a/builtin-fetch.c
+++ b/builtin-fetch.c
@@ -688,7 +688,8 @@ static void set_option(const char *name, const char *value)
 static int get_one_remote_for_fetch(struct remote *remote, void *priv)
 {
 	struct string_list *list = priv;
-	string_list_append(remote->name, list);
+	if (!remote->skip_default_update)
+		string_list_append(remote->name, list);
 	return 0;
 }
 
diff --git a/remote.c b/remote.c
index 73d33f2..beaf9fb 100644
--- a/remote.c
+++ b/remote.c
@@ -396,7 +396,8 @@ static int handle_config(const char *key, const char *value, void *cb)
 		remote->mirror = git_config_bool(key, value);
 	else if (!strcmp(subkey, ".skipdefaultupdate"))
 		remote->skip_default_update = git_config_bool(key, value);
-
+	else if (!strcmp(subkey, ".skipfetchall"))
+		remote->skip_default_update = git_config_bool(key, value);
 	else if (!strcmp(subkey, ".url")) {
 		const char *v;
 		if (git_config_string(&v, key, value))
-- 
1.6.5.1.69.g36942

^ permalink raw reply related

* [RFC/PATCH 2/4] Teach the --multiple option to 'git fetch'
From: Björn Gustavsson @ 2009-11-08 15:46 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano

Add the --multiple option to specify that all arguments are either
groups or remotes. The primary reason for adding this option is
to allow us to re-implement 'git remote update' using fetch.

Signed-off-by: Björn Gustavsson <bgustavsson@gmail.com>
---
 builtin-fetch.c |   10 +++++++++-
 1 files changed, 9 insertions(+), 1 deletions(-)

diff --git a/builtin-fetch.c b/builtin-fetch.c
index a520c1b..7926658 100644
--- a/builtin-fetch.c
+++ b/builtin-fetch.c
@@ -24,7 +24,7 @@ enum {
 	TAGS_SET = 2
 };
 
-static int all, append, force, keep, update_head_ok, verbosity;
+static int all, append, force, keep, multiple, update_head_ok, verbosity;
 static int tags = TAGS_DEFAULT;
 static const char *depth;
 static const char *upload_pack;
@@ -41,6 +41,8 @@ static struct option builtin_fetch_options[] = {
 		   "path to upload pack on remote end"),
 	OPT_BOOLEAN('f', "force", &force,
 		    "force overwrite of local branch"),
+	OPT_BOOLEAN('m', "multiple", &multiple,
+		    "fetch from multiple remotes"),
 	OPT_SET_INT('t', "tags", &tags,
 		    "fetch all tags and associated objects", TAGS_SET),
 	OPT_SET_INT('n', NULL, &tags,
@@ -838,6 +840,12 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
 		/* No arguments -- use default remote */
 		remote = remote_get(NULL);
 		result = fetch_one(remote, argc, argv);
+	} else if (multiple) {
+		/* All arguments are assumed to be remotes or groups */
+		for (i = 0; i < argc; i++)
+			if (!add_remote_or_group(argv[i], &list))
+				die("No such remote or remote group: %s", argv[i]);
+		result = fetch_multiple(&list);
 	} else {
 		/* Single remote or group */
 		(void) add_remote_or_group(argv[0], &list);
-- 
1.6.5.1.69.g36942

^ permalink raw reply related

* [RFC/PATCH 1/4] Teach the --all option to 'git fetch'
From: Björn Gustavsson @ 2009-11-08 15:45 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano

'git remote' is meant for managing remotes and 'git fetch' is meant
for actually fetching data from remote repositories. Therefore, it is
not logical that you must use 'git remote update' to fetch from
more than one repository at once.

Add the --all option to 'git fetch', to tell it to attempt to fetch
from all remotes. Also, if --all is not given, the <repository>
argument is allowed to be the name of a group, to allow fetching
from all repositories in the group.

Other options except -v and -q are silently ignored.

Signed-off-by: Björn Gustavsson <bgustavsson@gmail.com>
---
 Documentation/git-fetch.txt |    5 ++
 builtin-fetch.c             |  149 +++++++++++++++++++++++++++++++++++++-----
 t/t5514-fetch-all.sh        |   76 ++++++++++++++++++++++
 3 files changed, 212 insertions(+), 18 deletions(-)
 create mode 100755 t/t5514-fetch-all.sh

diff --git a/Documentation/git-fetch.txt b/Documentation/git-fetch.txt
index f2483d6..9172454 100644
--- a/Documentation/git-fetch.txt
+++ b/Documentation/git-fetch.txt
@@ -10,6 +10,8 @@ SYNOPSIS
 --------
 'git fetch' <options> <repository> <refspec>...
 
+'git fetch' --all <options>
+
 
 DESCRIPTION
 -----------
@@ -31,6 +33,9 @@ branches you are not interested in, you will not get them.
 
 OPTIONS
 -------
+--all::
+	Fetch all remotes.
+
 include::fetch-options.txt[]
 
 include::pull-fetch-param.txt[]
diff --git a/builtin-fetch.c b/builtin-fetch.c
index a35a6f8..a520c1b 100644
--- a/builtin-fetch.c
+++ b/builtin-fetch.c
@@ -14,6 +14,7 @@
 
 static const char * const builtin_fetch_usage[] = {
 	"git fetch [options] [<repository> <refspec>...]",
+	"git fetch --all [options]",
 	NULL
 };
 
@@ -23,7 +24,7 @@ enum {
 	TAGS_SET = 2
 };
 
-static int append, force, keep, update_head_ok, verbosity;
+static int all, append, force, keep, update_head_ok, verbosity;
 static int tags = TAGS_DEFAULT;
 static const char *depth;
 static const char *upload_pack;
@@ -32,6 +33,8 @@ static struct transport *transport;
 
 static struct option builtin_fetch_options[] = {
 	OPT__VERBOSITY(&verbosity),
+	OPT_BOOLEAN(0, "all", &all,
+		    "fetch from all remotes"),
 	OPT_BOOLEAN('a', "append", &append,
 		    "append to .git/FETCH_HEAD instead of overwriting"),
 	OPT_STRING(0, "upload-pack", &upload_pack, "PATH",
@@ -680,27 +683,89 @@ static void set_option(const char *name, const char *value)
 			name, transport->url);
 }
 
-int cmd_fetch(int argc, const char **argv, const char *prefix)
+static int get_one_remote_for_fetch(struct remote *remote, void *priv)
+{
+	struct string_list *list = priv;
+	string_list_append(remote->name, list);
+	return 0;
+}
+
+struct remote_group_data {
+	const char *name;
+	struct string_list *list;
+};
+
+static int get_remote_group(const char *key, const char *value, void *priv)
+{
+	struct remote_group_data *g = priv;
+
+	if (!prefixcmp(key, "remotes.") &&
+			!strcmp(key + 8, g->name)) {
+		/* split list by white space */
+		int space = strcspn(value, " \t\n");
+		while (*value) {
+			if (space > 1) {
+				string_list_append(xstrndup(value, space),
+						   g->list);
+			}
+			value += space + (value[space] != '\0');
+			space = strcspn(value, " \t\n");
+		}
+	}
+
+	return 0;
+}
+
+static int add_remote_or_group(const char *name, struct string_list *list)
+{
+	int prev_nr = list->nr;
+	struct remote_group_data g = { name, list };
+
+	git_config(get_remote_group, &g);
+	if (list->nr == prev_nr) {
+		struct remote *remote;
+		if (!remote_is_configured(name))
+			return 0;
+		remote = remote_get(name);
+		string_list_append(remote->name, list);
+	}
+	return 1;
+}
+
+static int fetch_multiple(struct string_list *list)
+{
+	int i, result = 0;
+	const char *argv[] = { "fetch", NULL, NULL, NULL, NULL };
+	int argc = 1;
+
+	if (verbosity >= 2)
+		argv[argc++] = "-v";
+	if (verbosity >= 1)
+		argv[argc++] = "-v";
+	else if (verbosity < 0)
+		argv[argc++] = "-q";
+
+	for (i = 0; i < list->nr; i++) {
+		const char *name = list->items[i].string;
+		argv[argc] = name;
+		if (verbosity >= 0)
+			printf("Fetching %s\n", name);
+		if (run_command_v_opt(argv, RUN_GIT_CMD)) {
+			error("Could not fetch %s", name);
+			result = 1;
+		}
+	}
+
+	return result;
+}
+
+static int fetch_one(struct remote *remote, int argc, const char **argv)
 {
-	struct remote *remote;
 	int i;
 	static const char **refs = NULL;
 	int ref_nr = 0;
 	int exit_code;
 
-	/* Record the command line for the reflog */
-	strbuf_addstr(&default_rla, "fetch");
-	for (i = 1; i < argc; i++)
-		strbuf_addf(&default_rla, " %s", argv[i]);
-
-	argc = parse_options(argc, argv, prefix,
-			     builtin_fetch_options, builtin_fetch_usage, 0);
-
-	if (argc == 0)
-		remote = remote_get(NULL);
-	else
-		remote = remote_get(argv[0]);
-
 	if (!remote)
 		die("Where do you want to fetch from today?");
 
@@ -716,10 +781,10 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
 	if (depth)
 		set_option(TRANS_OPT_DEPTH, depth);
 
-	if (argc > 1) {
+	if (argc > 0) {
 		int j = 0;
 		refs = xcalloc(argc + 1, sizeof(const char *));
-		for (i = 1; i < argc; i++) {
+		for (i = 0; i < argc; i++) {
 			if (!strcmp(argv[i], "tag")) {
 				char *ref;
 				i++;
@@ -746,3 +811,51 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
 	transport = NULL;
 	return exit_code;
 }
+
+int cmd_fetch(int argc, const char **argv, const char *prefix)
+{
+	int i;
+	struct string_list list = { NULL, 0, 0, 0 };
+	struct remote *remote;
+	int result = 0;
+
+	/* Record the command line for the reflog */
+	strbuf_addstr(&default_rla, "fetch");
+	for (i = 1; i < argc; i++)
+		strbuf_addf(&default_rla, " %s", argv[i]);
+
+	argc = parse_options(argc, argv, prefix,
+			     builtin_fetch_options, builtin_fetch_usage, 0);
+
+	if (all) {
+		if (argc == 1)
+			die("fetch --all does not take a repository argument");
+		else if (argc > 1)
+			die("fetch --all does not make sense with refspecs");
+		(void) for_each_remote(get_one_remote_for_fetch, &list);
+		result = fetch_multiple(&list);
+	} else if (argc == 0) {
+		/* No arguments -- use default remote */
+		remote = remote_get(NULL);
+		result = fetch_one(remote, argc, argv);
+	} else {
+		/* Single remote or group */
+		(void) add_remote_or_group(argv[0], &list);
+		if (list.nr > 1) {
+			/* More than one remote */
+			if (argc > 1)
+				die("Fetching a group and specifying refspecs does not make sense");
+			result = fetch_multiple(&list);
+		} else {
+			/* Zero or one remotes */
+			remote = remote_get(argv[0]);
+			result = fetch_one(remote, argc-1, argv+1);
+		}
+	}
+
+	/* All names were strdup()ed or strndup()ed */
+	list.strdup_strings = 1;
+	string_list_clear(&list, 0);
+
+	return result;
+}
diff --git a/t/t5514-fetch-all.sh b/t/t5514-fetch-all.sh
new file mode 100755
index 0000000..25244bf
--- /dev/null
+++ b/t/t5514-fetch-all.sh
@@ -0,0 +1,76 @@
+#!/bin/sh
+
+test_description='fetch --all works correctly'
+
+. ./test-lib.sh
+
+setup_repository () {
+	mkdir "$1" && (
+	cd "$1" &&
+	git init &&
+	>file &&
+	git add file &&
+	test_tick &&
+	git commit -m "Initial" &&
+	git checkout -b side &&
+	>elif &&
+	git add elif &&
+	test_tick &&
+	git commit -m "Second" &&
+	git checkout master
+	)
+}
+
+test_expect_success setup '
+	setup_repository one &&
+	setup_repository two &&
+	(
+		cd two && git branch another
+	) &&
+	git clone --mirror two three
+	git clone one test
+'
+
+cat > test/expect << EOF
+  one/master
+  one/side
+  origin/HEAD -> origin/master
+  origin/master
+  origin/side
+  three/another
+  three/master
+  three/side
+  two/another
+  two/master
+  two/side
+EOF
+
+test_expect_success 'git fetch --all' '
+	(cd test &&
+	 git remote add one ../one &&
+	 git remote add two ../two &&
+	 git remote add three ../three &&
+	 git fetch --all &&
+	 git branch -r > output &&
+	 test_cmp expect output)
+'
+
+test_expect_success 'git fetch --all should continue if a remote has errors' '
+	(git clone one test2 &&
+	 cd test2 &&
+	 git remote add bad ../non-existing &&
+	 git remote add one ../one &&
+	 git remote add two ../two &&
+	 git remote add three ../three &&
+	 test_must_fail git fetch --all &&
+	 git branch -r > output &&
+	 test_cmp ../test/expect output)
+'
+
+test_expect_success 'git fetch --all does not allow non-option arguments' '
+	(cd test &&
+	 test_must_fail git fetch --all origin &&
+	 test_must_fail git fetch --all origin master)
+'
+
+test_done
-- 
1.6.5.1.69.g36942

^ permalink raw reply related

* [RFC/PATCH 0/4] Re-implement 'remote update' using 'fetch'
From: Björn Gustavsson @ 2009-11-08 15:44 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano

After having done my previous patch to implement 'git fetch --all'
I decided to implement as much functionality in 'git fetch' to
make it possibility to re-implement 'git remote update' in terms of
'git fetch'.

The following things are currently missing from the patch series:

* updated documentation
* test cases for the group functionality in fetch
* support for 'git remote update --prune'

There is also a slight backward incompatibility that I know of (see the commit
message for the last commit). I could fix that, if there are
people depending on it.

I have no idea how much of the group functionality is really used. If someone
knows that "no-one uses THIS feature and" it would be nice to know.

Björn Gustavsson (4):
  Teach the --all option to 'git fetch'
  Teach the --multiple option to 'git fetch'
  Add the configure variable skipFetchAll
  Re-implement 'git remote update' using 'git fetch'

 Documentation/git-fetch.txt |    5 ++
 builtin-fetch.c             |  158 ++++++++++++++++++++++++++++++++++++++-----
 builtin-remote.c            |   86 +++++++----------------
 remote.c                    |    3 +-
 t/t5514-fetch-all.sh        |   76 +++++++++++++++++++++
 5 files changed, 249 insertions(+), 79 deletions(-)
 create mode 100755 t/t5514-fetch-all.sh

^ permalink raw reply

* Re: [PATCH] Teach the --all option to 'git fetch'
From: Björn Gustavsson @ 2009-11-08 15:18 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vaayxfji4.fsf@alter.siamese.dyndns.org>

2009/11/8 Junio C Hamano <gitster@pobox.com>:
> Björn Gustavsson <bgustavsson@gmail.com> writes:
>
> Please drop the "because I said so" part, as I made myself clear in the
> message I was speaking as mere one-of-participants to the project, not as
> the maintainer.

OK.

> Very nice.  I like the simplicity of this.

Thanks!

> Hopefully after the parse_options() we can inspect the "repo" argument to
> see if it names remote groups and transplant the support for that from
> "remote update" codepath into this, right?

Yes, it can be done, but it will lose some of its simplicity. I'll send a new
patch series that do that soon.

/Björn

-- 
Björn Gustavsson, Erlang/OTP, Ericsson AB

^ permalink raw reply

* Re: [gitweb feature request] Release snapshots with vX.X.X tags [closed]
From: Bram Neijt @ 2009-11-08 14:15 UTC (permalink / raw)
  To: Git mailing list
In-Reply-To: <m3tyx5rv6j.fsf@localhost.localdomain>

Dear Jakub,

Thank you for your response, reading the thread you mentioned [1], I
have seen that my feature is already included in the patch in progress
there. I will simply wait for that patch to get through.

I hereby declare this thread closed.

Greetings,
  Bram

[1] http://thread.gmane.org/gmane.comp.version-control.git/132366

On Sun, 2009-11-08 at 05:40 -0800, Jakub Narebski wrote:
> Bram Neijt <bneijt@gmail.com> writes:
> 
> > I would like to create release snapshots with a git tag like "v0.0.1".
> > For proper Debian packaging, a release snapshot of tag "v0.0.1" would
> > have to be named "project-0.0.1.tar.gz" and contain a single directory
> > with "project-0.0.1/" in the archive.
> > 
> > Attached is a very dirty patch to the current head of gitweb.perl to
> > change the snapshot if the requested hash has a tag which matches
> > "m/^v(.+)\^0$/". This regular expression will probably have to be more
> > strict then that in the future, but my main concern is the quality of
> > the patch, and whether or not this feature is something the mainstream
> > would appreciate.
> > 
> > My question to you all is: would this feature be considered as an
> > addition, and if so what would be the best way to get this patch into
> > shape for inclusion?
> 
> See Documentation/SubmittingPatches in git sources or in gitweb:
>   http://git.kernel.org/?p=git/git.git;a=blob;f=Documentation/SubmittingPatches;hb=HEAD
> Patch should be posted _inline_[1] (to make it easy to review the
> patch), and should use _unified_ (diff -u) format (to make it possible
> to apply patch correctly even if file changed in meantime) if you
> can't install git and use it (git format-patch) to generate a patch.
> 
> 
> By the way there is patch on git mailing list addressing part of
> mentioned issue:
>   "[PATCHv2 0/3] gitweb: Smarter snapshot names"
>   Message-ID: <1257606809-23287-1-git-send-email-jnareb@gmail.com>
>   http://thread.gmane.org/gmane.comp.version-control.git/132366
> (earlier version of this patch can be found in 'pu' branch as merge
> from 'mr/gitweb-snapshot' into pu).
> 
> This patch makes snapshot with name "project-version.tar.gz" to
> contain single directory "project-version/" in the archive.  Snapshot
> of tag *if requested* using 'refs/tags/v0.0.1' as 'h' (hash) parameter
> would have "project-v0.0.1.tar.gz" as proposed archive filename...
> but this patch doesn't make gitweb generate such links.
> 
> 
> [1] In very rare cases such as troubles with whitespace, line-wrapping
>     and encoding it might be better to attach it with text/plain
>     mimetype.
> 

^ permalink raw reply

* Re: [gitweb feature request] Release snapshots with vX.X.X tags
From: Jakub Narebski @ 2009-11-08 13:40 UTC (permalink / raw)
  To: Bram Neijt; +Cc: Git mailing list
In-Reply-To: <1257680442.14087.78.camel@owl>

Bram Neijt <bneijt@gmail.com> writes:

> I would like to create release snapshots with a git tag like "v0.0.1".
> For proper Debian packaging, a release snapshot of tag "v0.0.1" would
> have to be named "project-0.0.1.tar.gz" and contain a single directory
> with "project-0.0.1/" in the archive.
> 
> Attached is a very dirty patch to the current head of gitweb.perl to
> change the snapshot if the requested hash has a tag which matches
> "m/^v(.+)\^0$/". This regular expression will probably have to be more
> strict then that in the future, but my main concern is the quality of
> the patch, and whether or not this feature is something the mainstream
> would appreciate.
> 
> My question to you all is: would this feature be considered as an
> addition, and if so what would be the best way to get this patch into
> shape for inclusion?

See Documentation/SubmittingPatches in git sources or in gitweb:
  http://git.kernel.org/?p=git/git.git;a=blob;f=Documentation/SubmittingPatches;hb=HEAD
Patch should be posted _inline_[1] (to make it easy to review the
patch), and should use _unified_ (diff -u) format (to make it possible
to apply patch correctly even if file changed in meantime) if you
can't install git and use it (git format-patch) to generate a patch.


By the way there is patch on git mailing list addressing part of
mentioned issue:
  "[PATCHv2 0/3] gitweb: Smarter snapshot names"
  Message-ID: <1257606809-23287-1-git-send-email-jnareb@gmail.com>
  http://thread.gmane.org/gmane.comp.version-control.git/132366
(earlier version of this patch can be found in 'pu' branch as merge
from 'mr/gitweb-snapshot' into pu).

This patch makes snapshot with name "project-version.tar.gz" to
contain single directory "project-version/" in the archive.  Snapshot
of tag *if requested* using 'refs/tags/v0.0.1' as 'h' (hash) parameter
would have "project-v0.0.1.tar.gz" as proposed archive filename...
but this patch doesn't make gitweb generate such links.


[1] In very rare cases such as troubles with whitespace, line-wrapping
    and encoding it might be better to attach it with text/plain
    mimetype.

-- 
Jakub Narebski
Poland
ShadeHawk on #git

^ permalink raw reply

* Re: early days before git's invention
From: Jakub Narebski @ 2009-11-08 13:29 UTC (permalink / raw)
  To: Zhi Li; +Cc: git
In-Reply-To: <2986b3940911080423p4ccfe279ia00c995e1ea23fb9@mail.gmail.com>

Zhi Li <lizhi1215@gmail.com> writes:

> I have a question maybe not suitable to be put on this list. I'm just
> curious on git and Linux history. As what was said on wiki, Linux
> kernel was maintained by BitKeeper, then for some reason, BitKeeper
> can not be used, so git was invented. My question is what was used
> before BitKeeper, CVS? I don't think so. Then, just using file to
> manage?

For why BitKeeper could not be used, see:
  http://en.wikipedia.org/wiki/Git_(software)#Early_history
  http://git.or.cz/gitwiki/GitHistory
  http://kerneltrap.org/node/4982
  http://www.pcworld.idg.com.au/article/129776/after_controversy_torvalds_begins_work_git?fp=16&fpid=0

  http://better-scm.berlios.de/bk/demise-of-gratis-bitkeeper.html
  http://better-scm.berlios.de/bk/what-bitmover-got-wrong.html
  http://better-scm.berlios.de/bk/the-bitkeeper-ghost.html

Before BitKeeper Linux used tarballs (for releases) plus patches (for
changes); patches were send by email (on LKML).  Some maintainers used
tools like Quilt (or custom scripts) for patch management.


P.S. FreeBSD (IIRC) used / uses CVS for version control, but it has
quite different development model than Linux.

-- 
Jakub Narebski
Poland

^ permalink raw reply

* Re: early days before git's invention
From: Alejandro Riveira @ 2009-11-08 13:10 UTC (permalink / raw)
  To: git
In-Reply-To: <2986b3940911080423p4ccfe279ia00c995e1ea23fb9@mail.gmail.com>

El Sun, 08 Nov 2009 20:23:08 +0800, Zhi Li escribió:

> Hello list,
 
 Hi
[ ... ]

> used, so git was invented. My question is what was used before
> BitKeeper, CVS? I don't think so. Then, just using file to manage?

 Tarballs and patches :-)


> 
> Zhi

^ permalink raw reply

* Re: early days before git's invention
From: Johannes Schindelin @ 2009-11-08 13:12 UTC (permalink / raw)
  To: Zhi Li; +Cc: git
In-Reply-To: <2986b3940911080423p4ccfe279ia00c995e1ea23fb9@mail.gmail.com>

Hi,

On Sun, 8 Nov 2009, Zhi Li wrote:

> I have a question maybe not suitable to be put on this list. I'm just 
> curious on git and Linux history. As what was said on wiki, Linux kernel 
> was maintained by BitKeeper, then for some reason, BitKeeper can not be 
> used, so git was invented. My question is what was used before 
> BitKeeper, CVS? I don't think so. Then, just using file to manage?

Please read the transcript of Linus' talk about Git, it should contain all 
the information you are interested in [*1*]:

http://git.or.cz/gitwiki/LinusTalk200705Transcript

Ciao,
Dscho

Footnote *1*: For more background on the BitKeeper sadness: 
http://git.or.cz/gitwiki/GitHistory

^ permalink raw reply

* git top links: 2009-11
From: Felipe Contreras @ 2009-11-08 12:46 UTC (permalink / raw)
  To: git

Hi,

git top links is my attempt to gather all the links people have been
tagging as "git" in delicious.com[1] (these are not chosen by me).

The fancier blog version is here:
http://gitlog.wordpress.com/2009/11/08/git-top-links-2009-11/

These are the top links for November (and previous months). I haven’t
had time to work on this so that’s why I’m aggregating the months of
September and October too and the list is bigger than usual.

I’ve improved my tools to generate this, so hopefully I’ll be able to
post these more often. I’ll also post the tools soon just in case
people want to help too.

As you can see the first two links were overwhelmingly popular, it
seems people like stuff from Scott Chacon :)

1. Pro Git (483)
A book by Git experts to turn you into a Git expert.
http://progit.org/

2. Why You Should Switch from Subversion to Git (384)
Very detailed article that summarizes the advantages of Git over Subversion.
http://carsonified.com/blog/web-apps/why-you-should-switch-from-subversion-to-git/

3. learn.github (257)
Compilation of online training courses
http://learn.github.com/

4. Easy Version Control with Git (155)
Compact and comprehensive guide to get started with git.
http://net.tutsplus.com/tutorials/other/easy-version-control-with-git/

5. Gource (88)
Software version control visualization.
http://code.google.com/p/gource/

6. How We Made GitHub Fast (78)
Detailed explanation of how github was optimized in many areas.
http://github.com/blog/530-how-we-made-github-fast

7. Understanding Git Conceptually (75)
Simple yet useful tutorial to get familiar with Git concepts.
http://www.eecs.harvard.edu/~cduan/technical/git/

8. git (72)
Git's home-page
http://git-scm.com/

9. The Git Community Book (64)
http://book.git-scm.com/

10. Git - SVN Crash Course (54)
Straight-to-the-point crash course for subversion users
http://git.or.cz/course/svn.html

11. Setting up Gitorious on your own server (53)
Detailed guide to setup your own Gitorious.
http://cjohansen.no/en/ruby/setting_up_gitorious_on_your_own_server

12. Feature Branch (53)
Explanation of feature branches, continuous and promiscuous integration.
http://martinfowler.com/bliki/FeatureBranch.html

13. Hosting Git repositories, The Easy (and Secure) Way (47)
Instructions to setup gitosus for git hosting.
http://scie.nti.st/2007/11/14/hosting-git-repositories-the-easy-and-secure-way

14. pimping out git log (47)
Tips to prettify git log format.
http://www.jukie.net/~bart/blog/pimping-out-git-log

15. Setting up a new remote git repository (46)
http://toolmantim.com/articles/setting_up_a_new_remote_git_repository

16. GitCasts (43)
Comprehensive screen-casts showing git tricks
http://www.gitcasts.com/

17. Git: Your New Best Friend (42)
Straightforward introduction got Git, using command line and 'git gui'.
http://www.sitepoint.com/article/version-control-git/

18. Subversion ユーザーのための Git: 第 1 回 Git 入門 (41)
Simple introduction to Git for Subversion users (Japanese).
http://www.ibm.com/developerworks/jp/linux/library/l-git-subversion-1/?ca=drs-jp

19. github (39)
Popular Git hosting with social networking capabilities.
http://github.com/

20. Git and Microsoft Development: A Success Story (36)
A success story of Git on Windows development, and why other tools are not as
http://www.lexparse.com/2009/10/30/git-and-microsoft-development-a-success-story/

21. git ready (30)
Big collection of git tips
http://www.gitready.com/

22. Setting up a Mac to Work with Git and GitHub (29)
http://www.silverwareconsulting.com/index.cfm/2009/10/26/Setting-up-a-Mac-to-Work-with-Git-and-GitHub

23. 「入門 GIT」が神本である件。 git 利用者だけでなくすべての開発者が読むべき本 (29)
http://tech.kayac.com/archive/git-book.html

24. Everyday GIT With 20 Commands Or So (26)
http://www.kernel.org/pub/software/scm/git/docs/everyday.html

25. gity: The Git App For MAC (26)
http://macendeavor.com/gity

26. Git in One Hour (24)
http://www.oreillynet.com/pub/e/1394

27. そろそろ真剣にGitを・・・という人のための『ProGit』が鋭意翻訳進行中っぽい (23)
http://www.ideaxidea.com/archives/2009/09/progit_jp.html

28. [技術][Git]Git初心者が絶対に覚えておくべきコマンド (23)
http://d.hatena.ne.jp/idesaku/20091106/1257507849

29. Bananajour - Local git publication and collaboration (23)
Local ad-hoc git hosting with web interface and Bonjour discovery.
http://github.com/toolmantim/bananajour

30. TortoiseGit The coolest Interface to (Git) Version Control (22)
Comprehensive (all-in-one) GUI for Git, just like TortoiseSVN
http://code.google.com/p/tortoisegit/

31. GitX (20)
Attractive Git GUI made for Mac OS X.
http://gitx.frim.nl/

32. indefero: Better code management (19)
100% vendor lock-in free hosted code and project management.
http://www.indefero.net/

33. Git# --> Git for .NET and Mono (16)
Implementation of Git for the Dot.Net Framework and Mono.
http://www.eqqon.com/index.php/GitSharp

34. Why Git is Better than X (16)
http://whygitisbetterthanx.com/

35. Git Machine (15)
Interesting presentation about git and github
http://www.slideshare.net/err/git-machine

36. git ready: tig, the ncurses front-end to Git (15)
Intoduction to tig.
http://gitready.com/advanced/2009/07/31/tig-the-ncurses-front-end-to-git.html

37. Git Magic (15)
Comprehensive guide from getting started to advanced concepts.
http://www-cs-students.stanford.edu/~blynn/gitmagic/book.html

38. Starting with Git (14)
Guide to get started with Git in github.
http://blog.kirth.be/31/starting-with-git

39. Easy Fabric Deployment, Part 1: Git/Mercurial and SSH (14)
http://lincolnloop.com/blog/2009/sep/22/easy-fabric-deployment-part-1-gitmercurial-and-ssh/

40. Git Extensions (13)
Toolkit to make working with Git on Windows more intuitive.
http://code.google.com/p/gitextensions/

41. Rails deployment made easy with Inploy (12)
http://www.diegocarrion.com/2009/10/19/rails-deployment-made-easy-with-inploy/

42. chat sheets. $ cheat git (12)
http://cheat.errtheblog.com/s/git

43. Gitorious (12)
http://gitorious.org/

44. Using p4merge with Git (11)
http://onestepback.org/index.cgi/Tech/Git/UsingP4MergeWithGit.red

45. git merge vs git rebase: avoiding rebase hell (11)
http://jarrodspillers.com/articles/git-merge-vs-git-rebase-avoiding-rebase-hell/

46. Git – Working on a User Story (11)
http://www.rallydev.com/engblog/2009/09/15/git-working-on-a-user-story/

47. msysgit: Git on Windows (11)
http://code.google.com/p/msysgit/

48. Push to multiple Git repos (11)
http://afreshcup.com/2009/09/19/push-to-multiple-git-repos/

49. メモcache: gitの概念図 (11)
http://memocache.blogspot.com/2009/07/test.html

50. Pro Gitの日本語版PDF (10)
http://subtech.g.hatena.ne.jp/h2u/20090925/1253881931

51. When GitHub goes down... (10)
http://cloud.github.com/misc/down.html

52. The Git Parable (10)
http://tom.preston-werner.com/2009/05/19/the-git-parable.html

53. git ready: reflog, your safety net (10)
http://www.gitready.com/intermediate/2009/02/09/reflog-your-safety-net.html

54. Git For Windows Developers (10)
http://www.lostechies.com/blogs/jason_meridth/archive/2009/06/01/git-for-windows-developers-git-series-part-1.aspx

55. homebrew (9)
Packaging system for Mac OS X 10.5 and above.
http://github.com/mxcl/homebrew/tree

[1] http://delicious.com/tag/git

-- 
Felipe Contreras

^ permalink raw reply

* Re: gitk : french translation
From: Matthieu Moy @ 2009-11-08 12:33 UTC (permalink / raw)
  To: Nicolas Sebrecht; +Cc: Emmanuel Trillaud, Thomas Moulard, Git Mailing List
In-Reply-To: <20091107025439.GC13724@vidovic>

Nicolas Sebrecht <nicolas.s.dev@gmx.fr> writes:

>> > - make some consistency changes
>> >  * s/diff/différences/
>> >  * s/patch/correctif/ everywhere
>
> I disagree here. Words like "diff", "commit", "patch", etc should be
> kept as is. Translation of those terms make things harder for the users.

Metoo.

One day or another, the user will have to face the words "diff",
"commit" and "patch" even in a 100% french-speaking context (for
example when requesting help and someone answering "open a terminal
and type 'git commit --whatever'" or so).

Matching the command-line concepts and the GUI concepts is made really
hard by over-translating.

(and BTW, "correctif" is not a very good translation of "patch", since
a patch is not necessarilly a correction of something).

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/

^ permalink raw reply

* early days before git's invention
From: Zhi Li @ 2009-11-08 12:23 UTC (permalink / raw)
  To: git

Hello list,

I have a question maybe not suitable to be put on this list. I'm just
curious on git and Linux history. As what was said on wiki, Linux
kernel was maintained by BitKeeper, then for some reason, BitKeeper
can not be used, so git was invented. My question is what was used
before BitKeeper, CVS? I don't think so. Then, just using file to
manage?

Zhi

^ permalink raw reply

* [gitweb feature request] Release snapshots with vX.X.X tags
From: Bram Neijt @ 2009-11-08 11:40 UTC (permalink / raw)
  To: Git mailing list

[-- Attachment #1: Type: text/plain, Size: 820 bytes --]

Dear list members,

I would like to create release snapshots with a git tag like "v0.0.1".
For proper Debian packaging, a release snapshot of tag "v0.0.1" would
have to be named "project-0.0.1.tar.gz" and contain a single directory
with "project-0.0.1/" in the archive.

Attached is a very dirty patch to the current head of gitweb.perl to
change the snapshot if the requested hash has a tag which matches
"m/^v(.+)\^0$/". This regular expression will probably have to be more
strict then that in the future, but my main concern is the quality of
the patch, and whether or not this feature is something the mainstream
would appreciate.

My question to you all is: would this feature be considered as an
addition, and if so what would be the best way to get this patch into
shape for inclusion?

Greetings,
  Bram Neijt


[-- Attachment #2: tag_version_snapshot_detection.patch --]
[-- Type: text/x-patch, Size: 448 bytes --]

5269a5270,5274
> 	my $tagname = git_get_rev_name_tags($hash);
> 	my $tagversion = "";
> 	if ($tagname =~ m/^v(.+)\^0$/) {
>   	$tagversion = "-" + $1;
> 	}
5275a5281,5288
> 
> 	if($tagversion)	{
> 		$filename .= "$tagversion$known_snapshot_formats{$format}{'suffix'}";
> 	}
> 	else	{
> 		$filename .= "-$hash$known_snapshot_formats{$format}{'suffix'}";
> 	}
> 
5281c5294
< 		"--prefix=$name/", $hash);
---
> 		"--prefix=$name$tagversion/", $hash);

^ permalink raw reply

* [PATCH] Documentation: avoid tracking intermediate build products
From: Jonathan Nieder @ 2009-11-08 11:20 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Chris Johnsen

Add *.xml+, *.html+, *.texi+, and *.texi++ to .gitignore.

Cc: Chris Johnsen <chris_johnsen@pobox.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
Some of these files appeared in the "git status" output after an
interrupted build.  I hope I caught them all.

Good night,
Jonathan

 Documentation/.gitignore |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/Documentation/.gitignore b/Documentation/.gitignore
index d8edd90..22dbc0b 100644
--- a/Documentation/.gitignore
+++ b/Documentation/.gitignore
@@ -1,8 +1,12 @@
 *.xml
+*.xml+
 *.html
+*.html+
 *.[1-8]
 *.made
 *.texi
+*.texi+
+*.texi++
 git.info
 gitman.info
 howto-index.txt
-- 
1.6.5.2

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox