Git development
 help / color / mirror / Atom feed
* Re: [PATCH] Explicitly add the default "git pull" behaviour to .git/config on clone
From: Josef Weidendorfer @ 2006-12-07  2:49 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Andy Parkins, git
In-Reply-To: <Pine.LNX.4.63.0612070022180.28348@wbgn013.biozentrum.uni-wuerzburg.de>

On Thursday 07 December 2006 00:23, Johannes Schindelin wrote:
> Hi,
> 
> On Wed, 6 Dec 2006, Josef Weidendorfer wrote:
> 
> > On Wednesday 06 December 2006 13:07, Andy Parkins wrote:
> > > The [branch "master"] section is such that there is no change to the
> > > functionality of git-pull, but that functionality is now explicitly
> > > documented.
> > 
> > Nice. However, changing "git-clone" for this is an adhoc solution and 
> > looks wrong.
> 
> Not to me. There is _no_ other place to put this, if you want to help 
> people graps the concept of branch.*.merge.

As far as I understand, git-clone defaults to kind of a mirror operation
while changing remotes ref names slightly as tracking branches, and
afterwards, it sets up a local branch for development, which is
branched off from the branch which tracks remote's master.

IMHO there only should be one place/command which is creating new branches,
and which is called by other porcelain commands [*1*]. This way, if we add
some further action to "branching off" (like adding a default merge branch),
we will not miss any place where a new branch will be created, thus keeping
everything consistent.

Why should we not setup branch.*.merge when a create a new development
branch from a tracking branch via "git branch", or "git checkout -b" ?

Josef

[*1*] I recently made up my mind about this. I suggested a patch (see
"[PATCH/RFC] Convenient support of remote branches in git-checkout"
in the mail archive), which also set up "branch.*.merge" in a similar
way as this patch is doing. And I got - rightly - the same response

^ permalink raw reply

* Re: [PATCH] change the unpack limit treshold to a saner value
From: Nicolas Pitre @ 2006-12-07  3:24 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.64.0612061700120.3542@woody.osdl.org>

On Wed, 6 Dec 2006, Linus Torvalds wrote:

> We have a much easier time handling many loose packed objects than many 
> pack-files. For many reasons, but two really obvious ones:
> 
>  - pack-file indexes get read in on startup, and we maintain an explicit 
>    list of them. Having lots of pack-files adds overhead that doesn't 
>    exist for lots of loose objects.
> 
>  - loose files are spread out over 256 subdirectories to make lookup 
>    easier, packfiles are not (and always create an index file too).
> 
> So in general, as a trivial heuristic, you probably want about 512 times 
> as many loose objects as you want pack-files, i fonly because of the 
> latter issue, because you can much more easily handle lots of loose 
> objects than lots of pack-files. So it's _not_ a factor of 3. Or even 10.
> 
> But since there _is_ reason to do pack-files too, and since using too big 
> a value means that you never end up keeping a pack-file _at_all_ if you 
> pull often, I'd suggest that rather than use a limit of 512 you go for 
> something like 100-200 objects as the threshold (of course, the proper one 
> would depend on the distribution of the size of your pack-files, but I'll 
> just hand-wave and say that together with occasional re-packing, something 
> in that range is _generally_ going to be a good idea).

Note that this setting is currently observed for pushes not pulls.
On the pull side you currentli need to provide -k for not exploding 
packs.

So the question is what number of objects on average do pushes have?  If 
most pushes are below the treshold this is not going to be really 
useful.

And I think 5000 is definitely way too high.  10 might be too small 
indeed.  100 is maybe a good default to try out.



^ permalink raw reply

* [PATCH] cvsserver: Avoid miscounting bytes in Perl v5.8.x
From: Martin Langhoff @ 2006-12-07  3:38 UTC (permalink / raw)
  To: git, junkio; +Cc: Martin Langhoff

At some point between v5.6 and 5.8 Perl started to assume its input,
output and filehandles are UTF-8. This breaks the counting of bytes
for the CVS protocol, resulting in the client expecting less data
than we actually send, and storing truncated files.

Signed-off-by: Martin Langhoff <martin@catalyst.net.nz>
---

This has gone unfixed for quite a while. I thought I had seen
a patch posted addressing it, but it may have been for something else.

In fact, our heavily patched gitweb.cgi has needed a similar patch
as well. Snapshot downloads were getting corrupted until we added
use bytes; there too. I'm not sure how current gitweb does it though...

---
 git-cvsserver.perl |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/git-cvsserver.perl b/git-cvsserver.perl
index ca519b7..197014d 100755
--- a/git-cvsserver.perl
+++ b/git-cvsserver.perl
@@ -17,6 +17,7 @@
 
 use strict;
 use warnings;
+use bytes;
 
 use Fcntl;
 use File::Temp qw/tempdir tempfile/;
-- 
1.4.4.1.g7923a

^ permalink raw reply related

* Re: [PATCH] change the unpack limit treshold to a saner value
From: Linus Torvalds @ 2006-12-07  3:39 UTC (permalink / raw)
  To: Nicolas Pitre; +Cc: Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.64.0612062213500.2630@xanadu.home>



On Wed, 6 Dec 2006, Nicolas Pitre wrote:
> 
> Note that this setting is currently observed for pushes not pulls.
> On the pull side you currentli need to provide -k for not exploding 
> packs.

So noted.

> So the question is what number of objects on average do pushes have?  If 
> most pushes are below the treshold this is not going to be really 
> useful.

It will depend a lot on the project, and "where" in the project you are.

For example, for most end developers, the "push" is likely going to be a 
few commits (say, a days work). Probably on the order of a few tens to 
maybe a few hundred objects. It's actually hard to create a pack with less 
than ten objects if you have a few directory levels (a single small commit 
in the kernel is usually 5-7 objects: commit + 2-3 levels of directory + a 
couple of blobs).

For me, as I pull a big merge and push it out, a push can easily be in the 
thousands of objects, just because I merged other peoples combined work 
over several weeks.

And for a "mirror" server, it will depend on the granularity of the 
mirroring.

> And I think 5000 is definitely way too high.  10 might be too small 
> indeed.  100 is maybe a good default to try out.

I think 100 is a nice round number for humans. Worth trying.


^ permalink raw reply

* Re: [PATCH] Explicitly add the default "git pull" behaviour to .git/config on clone
From: Junio C Hamano @ 2006-12-07  3:44 UTC (permalink / raw)
  To: Josef Weidendorfer; +Cc: git
In-Reply-To: <200612070349.58521.Josef.Weidendorfer@gmx.de>

Josef Weidendorfer <Josef.Weidendorfer@gmx.de> writes:

> IMHO there only should be one place/command which is creating new branches,
> and which is called by other porcelain commands [*1*].

Giving an option to git branch to set something like this up
would be nice.  I would agree the division of labor you propose
is a good way to keep the scripts maintainable.

It however is a different matter if we would want to set up the
merge default always in the way you propose for a new branch at
the policy level.

It also is a different matter if "git branch" has enough
information to figure out which upstream "origin" needs to be
fetched from, given an origin SHA-1 expression to create a new
branch from, at the technical level

It entirely is possible to use the same remotes/origin/
hierarchy to track two physically different URLs (thus two
different "origin"s) on a mobile machine that has different
connectivity to the outside world depending on where you are
("that mirror is closer from here" and "I need to go over the
firewall while I am here").  Because they track the logically
same repository, it does not make sense to use different
hierarchies under remotes/ for this purpose.

In such a setup, "git branch new origin/for-public" would not be
able to tell which "origin" to fetch from, so it may not even be
feasible to do what you propose without an explicit help from
the command line option.  At least, however, the call to "git branch"
you would add as a part of this proposal to "git clone" would
know which URL, because at that point it would not even know
about the alternate connectivity yet.

> Why should we not setup branch.*.merge when a create a new development
> branch from a tracking branch via "git branch", or "git checkout -b"?

So while I am definitely in favor of the technical side of your
proposal to have "git checkout -b" use "git branch", instead of
doing it by hand, I think it would be an easier sell to separate
the policy from the discussion at least in the beginning.

I say this not because I disagree with your question: "Why
should we not?"  I do not have a ready-answer to that rhetorical
question yet.  But that is different from saying "it does not
make sense to do this setup because of such and such concrete
reasons", so I haven't formed an opinion on this policy matter
yet.


^ permalink raw reply

* [PATCH take 2] change the unpack limit treshold to a saner value
From: Nicolas Pitre @ 2006-12-07  4:01 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0612061420410.2630@xanadu.home>

Currently the treshold is 5000.  The likelihood of this value to ever be 
crossed for a single push is really small making it not really useful.

The optimal treshold for a pure space saving on a filesystem with 4kb 
blocks is 3.  However this is likely to create many small packs 
concentrating a large number of files in a single directory compared to 
the same objects which are spread over 256 directories when loose.  This 
means we would need 512 objects per pack on average to approximagte the 
same directory cost (a pack has 2 files because of the index).

But 512 is a really high value just like 5000 since most pushes are 
unlikely to have that many objects.  So let's try with a value of 100 
which should have a good balance between small pushes going to be 
exploded into loose objects and large pushes kept as whole packs.

This is not a replacement for periodic repacks of course.

Signed-off-by: Nicolas Pitre <nico@cam.org>

---

diff --git a/receive-pack.c b/receive-pack.c
index d62ed5b..9140312 100644
--- a/receive-pack.c
+++ b/receive-pack.c
@@ -11,7 +11,7 @@
 static const char receive_pack_usage[] = "git-receive-pack <git-dir>";
 
 static int deny_non_fast_forwards = 0;
-static int unpack_limit = 5000;
+static int unpack_limit = 100;
 static int report_status;
 

^ permalink raw reply related

* [PATCH] Documentation: reorganize cvs-migration.txt
From: J. Bruce Fields @ 2006-12-07  4:18 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7v7ix47wbr.fsf@assigned-by-dhcp.cox.net>

Modify cvs-migration.txt so it explains first how to develop against a
shared repository, then how to set up a shared repository, then how to
import a repository from cvs.  Though this seems chronologically
backwards, it's still readable in this order, and it puts the more
commonly needed material closer to the front.

Remove the annotate/pickaxe section; perhaps it can find a place elsewhere
in the future.  Remove most of the "why git is better than cvs" stuff from
the introduction.

Add some minor clarifications, including two that have come up several
times on the mailing list:

	1. Recommend committing any changes before running pull.
	2. Note that changes must be commited before they can be pushed.

Update the clone discussion to reflect the new --use-separate-remotes
default, and add a brief mention of git-cvsserver.

Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
---
 Documentation/cvs-migration.txt |  349 ++++++++++++---------------------------
 1 files changed, 109 insertions(+), 240 deletions(-)

diff --git a/Documentation/cvs-migration.txt b/Documentation/cvs-migration.txt
index 6812683..773fc99 100644
--- a/Documentation/cvs-migration.txt
+++ b/Documentation/cvs-migration.txt
@@ -1,113 +1,21 @@
 git for CVS users
 =================
 
-So you're a CVS user. That's OK, it's a treatable condition.  The job of
-this document is to put you on the road to recovery, by helping you
-convert an existing cvs repository to git, and by showing you how to use a
-git repository in a cvs-like fashion.
+Git differs from CVS in that every working tree contains a repository with
+a full copy of the project history, and no repository is inherently more
+important than any other.  However, you can emulate the CVS model by
+designating a single shared repository which people can synchronize with;
+this document explains how to do that.
 
 Some basic familiarity with git is required.  This
 link:tutorial.html[tutorial introduction to git] should be sufficient.
 
-First, note some ways that git differs from CVS:
-
-  * Commits are atomic and project-wide, not per-file as in CVS.
-
-  * Offline work is supported: you can make multiple commits locally,
-    then submit them when you're ready.
-
-  * Branching is fast and easy.
-
-  * Every working tree contains a repository with a full copy of the
-    project history, and no repository is inherently more important than
-    any other.  However, you can emulate the CVS model by designating a
-    single shared repository which people can synchronize with; see below
-    for details.
-
-Importing a CVS archive
------------------------
-
-First, install version 2.1 or higher of cvsps from
-link:http://www.cobite.com/cvsps/[http://www.cobite.com/cvsps/] and make
-sure it is in your path.  The magic command line is then
-
--------------------------------------------
-$ git cvsimport -v -d <cvsroot> -C <destination> <module>
--------------------------------------------
-
-This puts a git archive of the named CVS module in the directory
-<destination>, which will be created if necessary.  The -v option makes
-the conversion script very chatty.
-
-The import checks out from CVS every revision of every file.  Reportedly
-cvsimport can average some twenty revisions per second, so for a
-medium-sized project this should not take more than a couple of minutes.
-Larger projects or remote repositories may take longer.
-
-The main trunk is stored in the git branch named `origin`, and additional
-CVS branches are stored in git branches with the same names.  The most
-recent version of the main trunk is also left checked out on the `master`
-branch, so you can start adding your own changes right away.
-
-The import is incremental, so if you call it again next month it will
-fetch any CVS updates that have been made in the meantime.  For this to
-work, you must not modify the imported branches; instead, create new
-branches for your own changes, and merge in the imported branches as
-necessary.
-
-Development Models
-------------------
-
-CVS users are accustomed to giving a group of developers commit access to
-a common repository.  In the next section we'll explain how to do this
-with git.  However, the distributed nature of git allows other development
-models, and you may want to first consider whether one of them might be a
-better fit for your project.
-
-For example, you can choose a single person to maintain the project's
-primary public repository.  Other developers then clone this repository
-and each work in their own clone.  When they have a series of changes that
-they're happy with, they ask the maintainer to pull from the branch
-containing the changes.  The maintainer reviews their changes and pulls
-them into the primary repository, which other developers pull from as
-necessary to stay coordinated.  The Linux kernel and other projects use
-variants of this model.
-
-With a small group, developers may just pull changes from each other's
-repositories without the need for a central maintainer.
-
-Emulating the CVS Development Model
+Developing against a CVS repository
 -----------------------------------
 
-Start with an ordinary git working directory containing the project, and
-remove the checked-out files, keeping just the bare .git directory:
-
-------------------------------------------------
-$ mv project/.git /pub/repo.git
-$ rm -r project/
-------------------------------------------------
-
-Next, give every team member read/write access to this repository.  One
-easy way to do this is to give all the team members ssh access to the
-machine where the repository is hosted.  If you don't want to give them a
-full shell on the machine, there is a restricted shell which only allows
-users to do git pushes and pulls; see gitlink:git-shell[1].
-
-Put all the committers in the same group, and make the repository
-writable by that group:
-
-------------------------------------------------
-$ chgrp -R $group repo.git
-$ find repo.git -mindepth 1 -type d |xargs chmod ug+rwx,g+s
-$ GIT_DIR=repo.git git repo-config core.sharedrepository true
-------------------------------------------------
-
-Make sure committers have a umask of at most 027, so that the directories
-they create are writable and searchable by other group members.
-
-Suppose this repository is now set up in /pub/repo.git on the host
+Suppose a shared repository is set up in /pub/repo.git on the host
 foo.com.  Then as an individual committer you can clone the shared
-repository:
+repository over ssh with:
 
 ------------------------------------------------
 $ git clone foo.com:/pub/repo.git/ my-project
@@ -121,7 +29,8 @@ $ git pull origin
 ------------------------------------------------
 
 which merges in any work that others might have done since the clone
-operation.
+operation.  If there are uncommitted changes in your working tree, commit
+them first before running git pull.
 
 [NOTE]
 ================================
@@ -129,20 +38,22 @@ The first `git clone` places the following in the
 `my-project/.git/remotes/origin` file, and that's why the previous step
 and the next step both work.
 ------------
-URL: foo.com:/pub/project.git/ my-project
-Pull: master:origin
+URL: foo.com:/pub/project.git/
+Pull: refs/heads/master:refs/remotes/origin/master
 ------------
 ================================
 
-You can update the shared repository with your changes using:
+You can update the shared repository with your changes by first commiting
+your changes, and then using:
 
 ------------------------------------------------
 $ git push origin master
 ------------------------------------------------
 
-If someone else has updated the repository more recently, `git push`, like
-`cvs commit`, will complain, in which case you must pull any changes
-before attempting the push again.
+to "push" those commits to the shared repository.  If someone else has
+updated the repository more recently, `git push`, like `cvs commit`, will
+complain, in which case you must pull any changes before attempting the
+push again.
 
 In the `git push` command above we specify the name of the remote branch
 to update (`master`).  If we leave that out, `git push` tries to update
@@ -151,21 +62,76 @@ in the local repository.  So the last `push` can be done with either of:
 
 ------------
 $ git push origin
-$ git push repo.shared.xz:/pub/scm/project.git/
+$ git push foo.com:/pub/project.git/
 ------------
 
 as long as the shared repository does not have any branches
 other than `master`.
 
-[NOTE]
-============
-Because of this behavior, if the shared repository and the developer's
-repository both have branches named `origin`, then a push like the above
-attempts to update the `origin` branch in the shared repository from the
-developer's `origin` branch.  The results may be unexpected, so it's
-usually best to remove any branch named `origin` from the shared
-repository.
-============
+Setting Up a Shared Repository
+------------------------------
+
+We assume you have already created a git repository for your project,
+possibly created from scratch or from a tarball (see the
+link:tutorial.html[tutorial]), or imported from an already existing CVS
+repository (see the next section).
+
+If your project's working directory is /home/alice/myproject, you can
+create a shared repository at /pub/repo.git with:
+
+------------------------------------------------
+$ git clone -bare /home/alice/myproject /pub/repo.git
+------------------------------------------------
+
+Next, give every team member read/write access to this repository.  One
+easy way to do this is to give all the team members ssh access to the
+machine where the repository is hosted.  If you don't want to give them a
+full shell on the machine, there is a restricted shell which only allows
+users to do git pushes and pulls; see gitlink:git-shell[1].
+
+Put all the committers in the same group, and make the repository
+writable by that group:
+
+------------------------------------------------
+$ cd /pub
+$ chgrp -R $group repo.git
+$ find repo.git -mindepth 1 -type d |xargs chmod ug+rwx,g+s
+$ GIT_DIR=repo.git git repo-config core.sharedrepository true
+------------------------------------------------
+
+Make sure committers have a umask of at most 027, so that the directories
+they create are writable and searchable by other group members.
+
+Importing a CVS archive
+-----------------------
+
+First, install version 2.1 or higher of cvsps from
+link:http://www.cobite.com/cvsps/[http://www.cobite.com/cvsps/] and make
+sure it is in your path.  The magic command line is then
+
+-------------------------------------------
+$ git cvsimport -v -d <cvsroot> -C <destination> <module>
+-------------------------------------------
+
+This puts a git archive of the named CVS module in the directory
+<destination>, which will be created if necessary.  The -v option makes
+the conversion script very chatty.
+
+The import checks out from CVS every revision of every file.  Reportedly
+cvsimport can average some twenty revisions per second, so for a
+medium-sized project this should not take more than a couple of minutes.
+Larger projects or remote repositories may take longer.
+
+The main trunk is stored in the git branch named `origin`, and additional
+CVS branches are stored in git branches with the same names.  The most
+recent version of the main trunk is also left checked out on the `master`
+branch, so you can start adding your own changes right away.
+
+The import is incremental, so if you call it again next month it will
+fetch any CVS updates that have been made in the meantime.  For this to
+work, you must not modify the imported branches; instead, create new
+branches for your own changes, and merge in the imported branches as
+necessary.
 
 Advanced Shared Repository Management
 -------------------------------------
@@ -178,127 +144,30 @@ You can enforce finer grained permissions using update hooks.  See
 link:howto/update-hook-example.txt[Controlling access to branches using
 update hooks].
 
-CVS annotate
-------------
+Providing CVS Access to a git Repository
+----------------------------------------
+
+It is also possible to provide true CVS access to a git repository, so
+that developers can still use CVS; see gitlink:git-cvsserver[1] for
+details.
+
+Alternative Development Models
+------------------------------
+
+CVS users are accustomed to giving a group of developers commit access to
+a common repository.  As we've seen, this is also possible with git.
+However, the distributed nature of git allows other development models,
+and you may want to first consider whether one of them might be a better
+fit for your project.
+
+For example, you can choose a single person to maintain the project's
+primary public repository.  Other developers then clone this repository
+and each work in their own clone.  When they have a series of changes that
+they're happy with, they ask the maintainer to pull from the branch
+containing the changes.  The maintainer reviews their changes and pulls
+them into the primary repository, which other developers pull from as
+necessary to stay coordinated.  The Linux kernel and other projects use
+variants of this model.
 
-So, something has gone wrong, and you don't know whom to blame, and
-you're an ex-CVS user and used to do "cvs annotate" to see who caused
-the breakage. You're looking for the "git annotate", and it's just
-claiming not to find such a script. You're annoyed.
-
-Yes, that's right.  Core git doesn't do "annotate", although it's
-technically possible, and there are at least two specialized scripts out
-there that can be used to get equivalent information (see the git
-mailing list archives for details). 
-
-git has a couple of alternatives, though, that you may find sufficient
-or even superior depending on your use.  One is called "git-whatchanged"
-(for obvious reasons) and the other one is called "pickaxe" ("a tool for
-the software archaeologist"). 
-
-The "git-whatchanged" script is a truly trivial script that can give you
-a good overview of what has changed in a file or a directory (or an
-arbitrary list of files or directories).  The "pickaxe" support is an
-additional layer that can be used to further specify exactly what you're
-looking for, if you already know the specific area that changed.
-
-Let's step back a bit and think about the reason why you would
-want to do "cvs annotate a-file.c" to begin with.
-
-You would use "cvs annotate" on a file when you have trouble
-with a function (or even a single "if" statement in a function)
-that happens to be defined in the file, which does not do what
-you want it to do.  And you would want to find out why it was
-written that way, because you are about to modify it to suit
-your needs, and at the same time you do not want to break its
-current callers.  For that, you are trying to find out why the
-original author did things that way in the original context.
-
-Many times, it may be enough to see the commit log messages of
-commits that touch the file in question, possibly along with the
-patches themselves, like this:
-
-	$ git-whatchanged -p a-file.c
-
-This will show log messages and patches for each commit that
-touches a-file.
-
-This, however, may not be very useful when this file has many
-modifications that are not related to the piece of code you are
-interested in.  You would see many log messages and patches that
-do not have anything to do with the piece of code you are
-interested in.  As an example, assuming that you have this piece
-of code that you are interested in in the HEAD version:
-
-	if (frotz) {
-		nitfol();
-	}
-
-you would use git-rev-list and git-diff-tree like this:
-
-	$ git-rev-list HEAD |
-	  git-diff-tree --stdin -v -p -S'if (frotz) {
-		nitfol();
-	}'
-
-We have already talked about the "\--stdin" form of git-diff-tree
-command that reads the list of commits and compares each commit
-with its parents (otherwise you should go back and read the tutorial).
-The git-whatchanged command internally runs
-the equivalent of the above command, and can be used like this:
-
-	$ git-whatchanged -p -S'if (frotz) {
-		nitfol();
-	}'
-
-When the -S option is used, git-diff-tree command outputs
-differences between two commits only if one tree has the
-specified string in a file and the corresponding file in the
-other tree does not.  The above example looks for a commit that
-has the "if" statement in it in a file, but its parent commit
-does not have it in the same shape in the corresponding file (or
-the other way around, where the parent has it and the commit
-does not), and the differences between them are shown, along
-with the commit message (thanks to the -v flag).  It does not
-show anything for commits that do not touch this "if" statement.
-
-Also, in the original context, the same statement might have
-appeared at first in a different file and later the file was
-renamed to "a-file.c".  CVS annotate would not help you to go
-back across such a rename, but git would still help you in such
-a situation.  For that, you can give the -C flag to
-git-diff-tree, like this:
-
-	$ git-whatchanged -p -C -S'if (frotz) {
-		nitfol();
-	}'
-
-When the -C flag is used, file renames and copies are followed.
-So if the "if" statement in question happens to be in "a-file.c"
-in the current HEAD commit, even if the file was originally
-called "o-file.c" and then renamed in an earlier commit, or if
-the file was created by copying an existing "o-file.c" in an
-earlier commit, you will not lose track.  If the "if" statement
-did not change across such a rename or copy, then the commit that
-does rename or copy would not show in the output, and if the
-"if" statement was modified while the file was still called
-"o-file.c", it would find the commit that changed the statement
-when it was in "o-file.c".
-
-NOTE: The current version of "git-diff-tree -C" is not eager
-  enough to find copies, and it will miss the fact that a-file.c
-  was created by copying o-file.c unless o-file.c was somehow
-  changed in the same commit.
-
-You can use the --pickaxe-all flag in addition to the -S flag.
-This causes the differences from all the files contained in
-those two commits, not just the differences between the files
-that contain this changed "if" statement:
-
-	$ git-whatchanged -p -C -S'if (frotz) {
-		nitfol();
-	}' --pickaxe-all
-
-NOTE: This option is called "--pickaxe-all" because -S
-  option is internally called "pickaxe", a tool for software
-  archaeologists.
+With a small group, developers may just pull changes from each other's
+repositories without the need for a central maintainer.
-- 
1.4.4.1.GIT

^ permalink raw reply related

* Re: [PATCH 5/5] git-svn: re-map repository URLs and UUIDs on SVK mirror paths
From: Sam Vilain @ 2006-12-07  0:20 UTC (permalink / raw)
  To: Eric Wong; +Cc: git
In-Reply-To: <20061205085804.GB27236@soma>

Eric Wong wrote:
> Upon further review, this would make 'git svn rebuild' behave
> unexpectedly (it would make the git-svn metadata, including .rev_db
> entries point to the original repo and not the SVK one).  This may not
> necessarily be a big deal, however.

Yes, that's the idea; a 'rebuild' should set it up to pull from the
original SVN repository directly.  That probably needs some documentation...

> Also, incremental fetches (or fetching more than 1k sequential
> revisions) would probably fail.  To fix this, read the offset of last
> entry in .rev_db instead of git-svn-id: from the last commit to get the
> last revision.  But since rebuild won't work as expected; losing the
> .rev_db file means you wouldn't be able to fetch from the SVK repo
> anymore (but the original upstream one will be fine).
> 
> One last thing: feature should be made optional.  I actually work
> day-to-day on a repository that was created with svm/SVN::Mirror,
> the original repository no longer exists; but the mirrored one
> still has these properties (I suppose I could remove the props
> server-side, but some people may not have the permissions).

ok, I'll work on that and the other issues you highlighted... possibly
the overhead of fetching the revprops during mirroring might hurt a
little for people not doing this, too.  Thanks for reviewing the patch!

Sam.



^ permalink raw reply

* Re: [PATCH] cvsserver: Avoid miscounting bytes in Perl v5.8.x
From: Junio C Hamano @ 2006-12-07  5:48 UTC (permalink / raw)
  To: Martin Langhoff; +Cc: git
In-Reply-To: <11654627303222-git-send-email-martin@catalyst.net.nz>

Martin Langhoff <martin@catalyst.net.nz> writes:

> At some point between v5.6 and 5.8 Perl started to assume its input,
> output and filehandles are UTF-8. This breaks the counting of bytes
> for the CVS protocol, resulting in the client expecting less data
> than we actually send, and storing truncated files.

Thanks.  Will queue for both maint and master.

^ permalink raw reply

* Re: [PATCH] Documentation: reorganize cvs-migration.txt
From: Junio C Hamano @ 2006-12-07  5:51 UTC (permalink / raw)
  To: J. Bruce Fields; +Cc: git
In-Reply-To: <20061207041805.GC3457@fieldses.org>

"J. Bruce Fields" <bfields@fieldses.org> writes:

> diff --git a/Documentation/cvs-migration.txt b/Documentation/cvs-migration.txt
> index 6812683..773fc99 100644
> --- a/Documentation/cvs-migration.txt
> +++ b/Documentation/cvs-migration.txt
> @@ -1,113 +1,21 @@

This conflicted in a funny way with your own commit but I think
this version (773fc99 blob) supersedes its contents.

I munged only one line, though.  The title of this section 
should not be "a CVS repository" but "a shared repository" for
obvious reasons ;-).

> +Developing against a CVS repository
>  -----------------------------------
>  
> +Suppose a shared repository is set up in /pub/repo.git on the host
>  foo.com.  Then as an individual committer you can clone the shared
> +repository over ssh with:
>  
>  ------------------------------------------------
>  $ git clone foo.com:/pub/repo.git/ my-project


^ permalink raw reply

* [PATCH] Add config example with respect to branch
From: Aneesh Kumar K.V @ 2006-12-07  6:36 UTC (permalink / raw)
  To: git, Junio C Hamano

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



[-- Attachment #2: 0001-Add-config-example-with-respect-to-branch.txt --]
[-- Type: text/plain, Size: 703 bytes --]

From: Aneesh Kumar K.V <aneesh.kumar@gmail.com>

Update config.txt with example with respect to branch
config variable. This give a better idea regarding
how branch names are expected.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@gmail.com>
---
 Documentation/config.txt |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 9090762..d3518d1 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -31,6 +31,11 @@ Example
 		external = "/usr/local/bin/gnu-diff -u"
 		renames = true
 
+	[branch "devel"]
+		remote = origin
+		merge = refs/heads/devel
+
+
 Variables
 ~~~~~~~~~
 
-- 
1.4.4.1.g278f-dirty


^ permalink raw reply related

* Re: Fast access git-rev-list output: some OS knowledge required
From: Marco Costalba @ 2006-12-07  6:46 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Johannes Schindelin, Shawn Pearce, Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0612061642440.3542@woody.osdl.org>

On 12/7/06, Linus Torvalds <torvalds@osdl.org> wrote:
>
>
> On Thu, 7 Dec 2006, Johannes Schindelin wrote:
> >
> > Because, depending on what you do, the revision machinery is not
> > reentrable. For example, if you filter by filename, the history is
> > rewritten in-memory to simulate a history where just that filename was
> > tracked, and nothing else. These changes are not cleaned up after calling
> > the internal revision machinery.
>
> Well, it really wouldn't be that hard to add a new library interface to
> "reset object state". We could fairly trivially either:
>

So the library approach sounds like the best?

Of course in this case the producer git-rev-list and the receiver use
the same address space.

In the case of a temporary file data is first copied to OS disk cache
buffers and then again to userspace, in qgit address space. But the
real pain is that the temporary file is always flushed to disk after
4-5 seconds from creation, also if under heavy read/write activity.
This is a problem for big repos. I really don't know how to workaround
this useless disk flush.

Finally, what about using some kind of shared memory at run time,
instead of _sharing_ developer libraries ;-) ? is it too messy?

Probably the concurrent reading while writing is possible without
syncro if the reader understands that a sequence of _two_ or more \0
it means the end of current write stream if producer is still running
or the end of data if producer is not running anymore. I use a similar
approach in the 'temporary file' patch where receiver is able to read
while producer writes without explicit synchronization. In that case a
read() of a block smaller then maximum with producer still running is
used as the 'break' condition in the receiver while loop.



^ permalink raw reply

* Re: git pull and merging.
From: Aneesh Kumar K.V @ 2006-12-07  6:46 UTC (permalink / raw)
  To: Josef Weidendorfer; +Cc: Johannes Schindelin, Junio C Hamano, git
In-Reply-To: <200612061744.31213.Josef.Weidendorfer@gmx.de>

Josef Weidendorfer wrote:
> On Wednesday 06 December 2006 11:05, Aneesh Kumar wrote:
>> [branch "devel"]
>>         remote = origin
>>         merge = devel
>>
>> [....]
>> Now i thought merge should be local reference. So i changed it to
>> merge = remotes/origin/devel.
>>
>> That also didn't work.
>>
>> Then i tried the name of the branch should be indicated as
>> "refs/heads/devel" . That also didn't work.
>>
>> So i guess i am missing something.
> 
> See man page of git-repo-config:
> 
>  branch.<name>.merge
>   When in branch <name>, it tells git fetch the default
>   remote branch to be merged.
> 
> I assume that the "devel" branch on the remote repo you cloned from
> is also "devel", more exactly "refs/heads/devel".
> 
> Now, instead of "git pull", git should default to
> 
> 	git pull origin refs/heads/devel:refs/remotes/origin/devel



this means the remote reference is refs/heads/devel and local tracking branch for that is refs/remotes/origin/devel.




> 
> ie. it should update the local tracking branch "refs/remotes/origin/devel"
> with the remote branch "refs/heads/devel".
> The tracking branch "refs/remotes/origin/devel" will be merged with current
> branch afterwards.
> 


That will be merged is the tricky part. 



> Now looking at the documentation for branch.<name>.merge, it talks
> about the remote branch, which is "refs/heads/devel" in your case, ie.
> the first part of the refspec of the full "git pull" command above.
> 

This is most confusing part. What merge indicate is not about refs/heads/devel
should track refs/remotes/origin/devel. That is specfied in the remote config option.

What merge indicate is that when in a local branch ( not the tracking one under remotes/origin)
which branch from remote need to be used to merge to the local branch.




> So, as you already posted (without explanation, therefore this mail),
> the config should be
> 
>  [branch "devel"]
>          remote = origin
>          merge = refs/heads/devel
> 
> However, "devel" alone should work here, as it can be matched with remote
> "refs/heads/devel". Seems to be a bug, as branch.<name>.merge seems to only
> being compared with the full canonical name in the implementation.


I guess we need to have a standard way of saying the branches. 

May be we want to document it in repo-config.

local branch on which changes can be made <branch-name>
local tracking branch refs/remotes/<remote-name>/<branch-name>
remote branch refs/heads/<branch-name>



^ permalink raw reply

* Re: [PATCH] Explicitly add the default "git pull" behaviour to .git/config on clone
From: Aneesh Kumar K.V @ 2006-12-07  6:49 UTC (permalink / raw)
  To: git
In-Reply-To: <200612061207.23437.andyparkins@gmail.com>

Andy Parkins wrote:
> Without any specification in the .git/config file, git-pull will execute
> "git-pull origin"; which in turn defaults to pull from the first "pull"
> definition for the remote, "origin".
> 
> This is a difficult set of defaults to track for a new user, and it's
> difficult to see what tells git to do this (especially when it is
> actually hard-coded behaviour).  To ameliorate this slightly, this patch
> explicitly specifies the default behaviour during a clone using the
> "branch" section of the config.
> 
> For example, a clone of a typical repository would create a .git/config
> containing:
>   [remote "origin"]
>   url = proto://host/repo.git
>   fetch = refs/heads/master:refs/remotes/origin/master
>   [branch "master"]
>   remote = origin
>   merge = refs/heads/master
> 
> The [branch "master"] section is such that there is no change to the
> functionality of git-pull, but that functionality is now explicitly
> documented.
> 
> Signed-off-by: Andy Parkins <andyparkins@gmail.com>
> ---
> This is really to help newbies.  By explicitly documenting the default
> behaviour, it makes it clearer what is going on.  It also means no routing
> through documentation to find out what config option needs changing.
> 
> It's possible that we would want to remove the default behaviour entirely
> if there is no "branch" definition in the config.  That would prevent
> accidents by users who don't know what pull does fully yet.
> 

I liked this. This avoid lot of confusion and the "magic" master  update.

-aneesh

^ permalink raw reply

* Re: how to revert changes in working tree?
From: Juergen Ruehle @ 2006-12-07  7:15 UTC (permalink / raw)
  To: Liu Yubao; +Cc: Shawn Pearce, Alex Riesen, git
In-Reply-To: <45777197.50805@gmail.com>

Liu Yubao writes:
 > Yes, you are very right.
 > 
 > $ git ls-files |tr A-Z a-z | sort | uniq -c |grep -v "1 "
 >       2 include/linux/netfilter/xt_connmark.h
 >       2 include/linux/netfilter/xt_dscp.h
 >       2 include/linux/netfilter/xt_mark.h
 >       2 include/linux/netfilter_ipv4/ipt_connmark.h
 >       2 include/linux/netfilter_ipv4/ipt_dscp.h
 >       2 include/linux/netfilter_ipv4/ipt_ecn.h
 >       2 include/linux/netfilter_ipv4/ipt_mark.h
 >       2 include/linux/netfilter_ipv4/ipt_tcpmss.h
 >       2 include/linux/netfilter_ipv4/ipt_tos.h
 >       2 include/linux/netfilter_ipv4/ipt_ttl.h
 >       2 include/linux/netfilter_ipv6/ip6t_hl.h
 >       2 include/linux/netfilter_ipv6/ip6t_mark.h
 >       2 net/ipv4/netfilter/ipt_ecn.c
 >       2 net/ipv4/netfilter/ipt_tos.c
 >       2 net/ipv4/netfilter/ipt_ttl.c
 >       2 net/ipv6/netfilter/ip6t_hl.c
 >       2 net/netfilter/xt_connmark.c
 >       2 net/netfilter/xt_dscp.c
 >       2 net/netfilter/xt_mark.c
 > 
 > poor Windows... :-(

Incidentally I have this in my tree for a while, but it is not good
enough for general use, because you really need the original (not
lowercased) file names to resolve the problem. But my shell scripting
magic is not up to that task.

diff --git a/templates/hooks--pre-commit b/templates/hooks--pre-commit
index 723a9ef..0ceb01b 100644
--- a/templates/hooks--pre-commit
+++ b/templates/hooks--pre-commit
@@ -7,6 +7,17 @@
 #
 # To enable this hook, make this file executable.

+# Detect case challenges
+
+case_challenge=`git ls-files | tr A-Z a-z | sort | uniq -d`
+if [ -n "$case_challenge" ]
+then
+       echo >&2 "index contains file names differing only in case."
+       echo >&2 "lowercase names follow:"
+       echo >&2 "$case_challenge"
+       exit 1
+fi
+
 # This is slightly modified from Andrew Morton's Perfect Patch.
 # Lines you introduce should not have trailing whitespace.
 # Also check for an indentation that has SP before a TAB.

^ permalink raw reply related

* Re: [PATCH take 2] change the unpack limit treshold to a saner value
From: Shawn Pearce @ 2006-12-07  7:59 UTC (permalink / raw)
  To: Nicolas Pitre; +Cc: Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.64.0612062244090.2630@xanadu.home>

Nicolas Pitre <nico@cam.org> wrote:
> Currently the treshold is 5000.  The likelihood of this value to ever be 
> crossed for a single push is really small making it not really useful.

I started that out at 5000 because it was a reasonably safe
threshold.  Users who didn't explicitly lower this value didn't
enable the feature.  But it was still useful on initial pushes into
a brand new repository when the project was very large.  For example
pushing git.git into a bare repository *sucked* before this change.

Yea, 5000 is probably too high.  Nice to see it drop.

-- 

^ permalink raw reply

* Bug in merge-recursive in virtual commit corner case
From: Shawn Pearce @ 2006-12-07  8:35 UTC (permalink / raw)
  To: git

So I managed to create a fairly complex set of branches which are all
merged back against each other at various points in time.  Two of
them have 3 merge bases according to git-merge-base.  Tonight I
tried to merge them together, but received the following wonderful
error from git-merge-recursive:

  fatal: unable to read source tree (4b825dc642cb6eb9a060e54bf8d69288fbee4904)

For those in the know, that's the empty tree.  This particular
repository does not have the empty tree anywhere in it, which is
why we can't read the object: it doesn't exist, and shouldn't exist.

Running `git-mktree </dev/null` to create the empty tree worked;
git-merge-recursive ran through and cleanly merged the two branches.
But the empty tree still shouldn't be in my repository, so a future
git-prune is just going to whack it again.  Yes, I know, I could
anchor it with a ref (.git/refs/empty-tree) but I shouldn't need
to use git-mktree and git-update-ref just to use git-merge-recursive.

I found the above error message in tree-diff.c's diff_tree_sha1
function.  I threw in debugging and found that the new tree was
the root tree of one branch and the base was the root tree of some
other revision.

Apparently the empty tree is being created in merge-recursive.c:

   1219     if (merged_common_ancestors == NULL) {
   1220         /* if there is no common ancestor, make an empty tree */
   1221         struct tree *tree = xcalloc(1, sizeof(struct tree));
   1222
   1223         tree->object.parsed = 1;
   1224         tree->object.type = OBJ_TREE;
   1225         hash_sha1_file(NULL, 0, tree_type, tree->object.sha1);
   1226         merged_common_ancestors = make_virtual_commit(tree, "ancestor");
   1227     }

So basically this code crashes if its ever used in a repository
that hasn't had a need for the empty tree before.  :-(

I've been unable to create an isolated test case.  I can't publish
the repository that I caused the case in either.

I'm not quite sure what the fix should be here: patch diff_tree_sha1
to know when it gets the empty tree, or create the object in
merge-recursive.c?

-- 

^ permalink raw reply

* Re: Topic descriptions
From: Andy Parkins @ 2006-12-07  8:37 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano
In-Reply-To: <7v4ps8y7un.fsf@assigned-by-dhcp.cox.net>

On Wednesday 2006, December 06 22:31, Junio C Hamano wrote:

> I am unlikely to use such a thing for the "What's in" message,
> though.  The part that talks about "what the current status is"
> is much easier to write when I need to talk about "the current";
> otherwise I'd be forced to remember to think if I need to update
> the information, every time I touch topic branches.

It wasn't so much the what's current - as you say that would be fairly 
ridiculous as it's so fluid.  It was more a description of the topic.  I've 
got tonnes of branches where I have quickly thought of an idea and started 
work on it, only to get bored and move on.  Describing a topic in such a 
short space as "ap/short-name" is hard.

The actual place it's stored isn't really relevant, more that I could see a 
use for it.  If it's going in the config I suppose all it needs is a 
magic "and so it shall be" hand wave.  It doesn't require any new code does 
it?


Andy
-- 
Dr Andrew Parkins, M Eng (Hons), AMIEE

^ permalink raw reply

* Re: What's cooking in git.git (topics)
From: Alexandre Julliard @ 2006-12-07  9:03 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.63.0612070035570.28348@wbgn013.biozentrum.uni-wuerzburg.de>

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

>> * js/shallow (Fri Nov 24 16:00:13 2006 +0100)
>> 
>>  Probably with a better documentation of its limitations and caveats, 
>>  this should be mergeable to 'master'.
>
> The more I see the missing reaction, the less sure I am this is a sensible 
> thing to do.

I'm not sure what reaction you expect, but this is something a lot of
our occasional Wine users are requesting. The Wine full history is
80Mb, and that's a big download if you just want to try a quick
patch. Now of course you won't see these users around here hacking on
shallow clone, most likely they just went and downloaded Wine from the
CVS mirror instead. But it's a shame to have to maintain a CVS mirror
just for that purpose...

-- 
Alexandre Julliard

^ permalink raw reply

* Re: Bug in merge-recursive in virtual commit corner case
From: Junio C Hamano @ 2006-12-07  9:13 UTC (permalink / raw)
  To: Shawn Pearce; +Cc: git
In-Reply-To: <20061207083531.GA22701@spearce.org>

Shawn Pearce <spearce@spearce.org> writes:

> I found the above error message in tree-diff.c's diff_tree_sha1
> function.  I threw in debugging and found that the new tree was
> the root tree of one branch and the base was the root tree of some
> other revision.
>
> Apparently the empty tree is being created in merge-recursive.c:
>
>    1219     if (merged_common_ancestors == NULL) {
>    1220         /* if there is no common ancestor, make an empty tree */
>    1221         struct tree *tree = xcalloc(1, sizeof(struct tree));
>    1222
>    1223         tree->object.parsed = 1;
>    1224         tree->object.type = OBJ_TREE;
>    1225         hash_sha1_file(NULL, 0, tree_type, tree->object.sha1);
>    1226         merged_common_ancestors = make_virtual_commit(tree, "ancestor");
>    1227     }
>
> So basically this code crashes if its ever used in a repository
> that hasn't had a need for the empty tree before.  :-(

I hit the same issue when I integrated Johannes's in-core merge;
I originally used hash_sha1_file() but that results in objects
that are supposed to be in the virtual parent unreadable when
merging the real children.  The key is to use write_sha1_file()
to actually create the needed objects, and trust later prune to
remove them.

Replace it with write_sha1_file() and you should be fine, I
think.

^ permalink raw reply

* Re: Topic descriptions
From: Junio C Hamano @ 2006-12-07  9:34 UTC (permalink / raw)
  To: Andy Parkins; +Cc: git
In-Reply-To: <200612070837.16412.andyparkins@gmail.com>

Andy Parkins <andyparkins@gmail.com> writes:

> The actual place it's stored isn't really relevant, more that I could see a 
> use for it.  If it's going in the config I suppose all it needs is a 
> magic "and so it shall be" hand wave.

I now have this in my .git/config:

-- >8 -- snippet from .git/config -- >8 --
[branch "ap/clone-origin"]
	description = set up a cloned repository with friendlier defaults.

[branch "jc/3way"]
	description = use three-way merge to preserve local changes upon branch switch and fast forward.
-- 8< --

and have the script attached at the end.  I can say:

	$ git-topic --base=master

to get something like that per-topic summary I sent out earlier.
The default $base is set to 'next' because usually I am
interested in keeping track of what could be merged but not yet
to next.

Hopefully gitweb (and perhaps gitk) can follow suit to read the
branch description from the same place.

-- >8 -- git-topic.perl -- >8 --
#!/usr/bin/perl -w
#
# Copyright (c) 2006 Junio C Hamano
#

use strict;
use Getopt::Long;

my $topic_pattern = '??/*';
my $base = 'next';
my @stage = qw(next pu);
my @mark = ('.', '?', '-', '+');
my $all = 0;

my @custom_stage;
my @custom_mark;
GetOptions("topic=s" => \$topic_pattern,
	   "base=s" => \$base,
	   "stage=s" => \@custom_stage,
	   "mark=s" => \@custom_mark,
	   "all!" => \$all)
    or die;

if (@custom_stage) { @stage = @custom_stage; }
if (@custom_mark) { @mark = @custom_mark; }

sub read_revs_short {
	my ($bottom, $top) = @_;
	my @revs;
	open(REVS, '-|', qw(git rev-list --no-merges), "$bottom..$top")
	    or die;
	while (<REVS>) {
		chomp;
		push @revs, $_;
	}
	close(REVS);
	return @revs;
}

sub read_revs {
	my ($bottom, $top, $mask) = @_;
	my @revs;
	open(REVS, '-|', qw(git rev-list --pretty=oneline --no-merges),
	     "$bottom..$top")
	    or die;
	while (<REVS>) {
		chomp;
		my ($sha1, $topic) = /^([0-9a-f]{40}) (.*)$/;
		push @revs, [$sha1, $topic, $mask];
	}
	close(REVS);
	return @revs;
}

sub describe_topic {
	my ($topic) = @_;
	open(CONF, '-|', qw(git repo-config --get),
		"branch.$topic.description")
		or die;
	my $it = join('',<CONF>);
	close(CONF);
	chomp($it);
	if ($it) {
		wrap_print("  $it");
	}
}

sub wrap_print {
	my ($string) = @_;
	format STDOUT =
~^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
	$string
 ~~^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
	$string
.
	write;
}

open(TOPIC, '-|', qw(git for-each-ref),
	'--sort=-authordate',
	'--format=%(objectname) %(authordate) %(refname)',
	"refs/heads/$topic_pattern")
	or die;

while (<TOPIC>) {
	chomp;
	my ($sha1, $date, $topic) = m|^([0-9a-f]{40})\s(.*?)\srefs/heads/(.+)$|
		or next;
	my @revs = read_revs($base, $sha1, (1<<@stage)-1);
	next unless (@revs || $all);

	my %revs = map { $_->[0] => $_ } @revs; # fast index
	for (my $i = 0; $i < @stage; $i++) {
		for my $item (read_revs_short($stage[$i], $sha1)) {
			if (exists $revs{$item}) {
				$revs{$item}[2] &= ~(1 << $i);
			}
		}
	}
	print "* $topic ($date)\n";
	describe_topic($topic);
	for my $item (@revs) {
		my $mark = $item->[2];
		if ($mark < @mark) {
			$mark = $mark[$mark];
		}
		wrap_print("$mark $item->[1]");
	}
}

^ permalink raw reply

* [PATCH 1/2] Allow users to require source branch on git-checkout -b.
From: Shawn O. Pearce @ 2006-12-07 10:01 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

I have recently observed a rather large number of users who forget
to specify the base revision when they start a new branch with
git-checkout -b.  Many of these users are shocked many hours and
commits later when their prior branch is now also part of the new
branch.  Nasty words about Git usually follow the discovery.

This introduces a new config option: checkout.requireSourceBranch,
which the user can set to make git-checkout -b require them to supply
not only the new branch name but also the initial version for that
branch.  This prevents the command from assuming the user meant HEAD
when they omitted an argument by accident.

To keep behavior backwards compatible with any existing scripts
this option is currently disabled by default, but it would be more
friendly to new users if the option was enabled by default.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
 Documentation/config.txt |    6 ++++++
 git-checkout.sh          |   12 +++++++++++-
 t/t3200-branch.sh        |   14 ++++++++++++++
 3 files changed, 31 insertions(+), 1 deletions(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 9090762..9d754c8 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -130,6 +130,12 @@ branch.<name>.merge::
 	When in branch <name>, it tells `git fetch` the default remote branch
 	to be merged.
 
+checkout.requireSourceBranch::
+	If true tells git-checkout -b to require the user to
+	supply two arguments, rather than assuming HEAD should
+	be the source version if only one argument is supplied.
+	Default is false, to stay compatible with prior behavior.
+
 pager.color::
 	A boolean to enable/disable colored output when the pager is in
 	use (default is true).
diff --git a/git-checkout.sh b/git-checkout.sh
index 737abd0..5f9fb6e 100755
--- a/git-checkout.sh
+++ b/git-checkout.sh
@@ -137,7 +137,17 @@ then
 	cd "$cdup"
 fi
 
-[ -z "$new" ] && new=$old && new_name="$old_name"
+# If we have no new name default to 'HEAD', unless we are
+# making a new branch and the user told us not to assume.
+if [ -z "$new" ]; then
+	if [ "$newbranch" ] &&
+	   [ Xtrue = "X`git-repo-config --bool checkout.requireSourceBranch`" ]
+	then
+		die "A source branch is required when creating a branch."
+	fi
+	new=$old
+	new_name="$old_name"
+fi
 
 # If we don't have an old branch that we're switching to,
 # and we don't have a new branch name for the target we
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index acb54b6..7e0c48b 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -70,4 +70,18 @@ test_expect_success \
         git-branch -d l/m &&
         git-branch l'
 
+test_expect_success \
+	'git checkout -b M works if checkout.requireSourceBranch not set' \
+	'git-checkout -b M'
+
+test_expect_failure \
+	'git checkout -b N fails if checkout.requireSourceBranch is set' \
+	'git-repo-config checkout.requireSourceBranch true
+	 git-checkout -b N'
+
+test_expect_success \
+	'git checkout -b N works if checkout.requireSourceBranch is false' \
+	'git-repo-config checkout.requireSourceBranch false
+	 git-checkout -b N'
+
 test_done
-- 
1.4.4.2.gb772

^ permalink raw reply related

* [PATCH 2/2] Optionally check for uncommitted changes before switching branches.
From: Shawn O. Pearce @ 2006-12-07 10:02 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <6ed9774cb95e873e76a4ac406dd740caf954bd3b.1165485618.git.spearce@spearce.org>

Lately I have noticed a number of users are forgetting that they
have uncommitted changes in their working directory when they switch
to another branch.  This causes the user to accidentally carry those
changes into the new branch, which is usually not where they wanted
to commit them.  A correlation does appear to exist between the user
being interrupted in the middle of their task and the branch switch,
indicating they simply got distracted and forgot what was going on.

Git shouldn't cause the user to make mistakes when it can help to
prevent them.  So now users may set checkout.requireCleanDirectory
to true in their config file to have git-checkout verify the working
directory is clean before switching branches.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
 Documentation/config.txt |    8 ++++++++
 git-checkout.sh          |   10 ++++++++++
 t/t3200-branch.sh        |   11 +++++++++++
 3 files changed, 29 insertions(+), 0 deletions(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 9d754c8..f10e8ac 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -136,6 +136,14 @@ checkout.requireSourceBranch::
 	be the source version if only one argument is supplied.
 	Default is false, to stay compatible with prior behavior.
 
+checkout.requireCleanDirectory::
+	If true tells git-checkout to verify there are no uncommitted
+	changes still in the index or working directory before
+	switching branches.  If uncommitted changes exist the -m
+	flag can be used to skip the check if the user really wanted
+	to carry those onto the new branch.  Default is false,
+	to stay compatible with prior behavior.
+
 pager.color::
 	A boolean to enable/disable colored output when the pager is in
 	use (default is true).
diff --git a/git-checkout.sh b/git-checkout.sh
index 5f9fb6e..c04b8c1 100755
--- a/git-checkout.sh
+++ b/git-checkout.sh
@@ -171,6 +171,16 @@ then
     git-read-tree --reset -u $new
 else
     git-update-index --refresh >/dev/null
+	if [ -n "$old" ] &&
+	   [ -z "$merge" ] &&
+	   [ Xtrue = "X`git-repo-config --bool checkout.requireCleanDirectory`" ]
+	then
+		if [ `git-diff-index --cached $old | wc -l` -gt 0 ] ||
+		   [ `git-diff-files | wc -l` -gt 0 ]
+		then
+			die "Working directory has uncommitted changes; commit, reset or use -m"
+		fi
+	fi
     merge_error=$(git-read-tree -m -u $old $new 2>&1) || (
 	case "$merge" in
 	'')
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index 7e0c48b..9429827 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -84,4 +84,15 @@ test_expect_success \
 	'git-repo-config checkout.requireSourceBranch false
 	 git-checkout -b N'
 
+test_expect_failure \
+	'git checkout -b O works only if tree is clean' \
+	'git-repo-config checkout.requireCleanDirectory true
+	 echo atest >atest
+	 git add atest
+	 git-checkout -b O'
+
+test_expect_success \
+	'git checkout -m -b O works' \
+	'git-checkout -m -b O'
+
 test_done
-- 

^ permalink raw reply related

* [PATCH 1/1] Make sure the empty tree exists when needed in merge-recursive.
From: Shawn O. Pearce @ 2006-12-07 10:17 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

There are some baseless merge cases where git-merge-recursive will
try to compare one of the branches against the empty tree.  However
most projects won't have the empty tree object in their object database
as Git does not normally create empty tree objects.  If the empty tree
object is missing then the merge process will die, as it cannot load the
object from the database.  The error message may make the user think that
their database is corrupt when its actually not.

So instead we should just create the empty tree object whenever it is
needed.  If the object already exists as a loose object then no harm
done.  Otherwise that loose object will be pruned away later by either
git-prune or git-prune-packed.

Thanks goes to Junio for suggesting this fix.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
 merge-recursive.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/merge-recursive.c b/merge-recursive.c
index cd2cc77..32e186c 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -1238,7 +1238,7 @@ static int merge(struct commit *h1,
 
 		tree->object.parsed = 1;
 		tree->object.type = OBJ_TREE;
-		hash_sha1_file(NULL, 0, tree_type, tree->object.sha1);
+		write_sha1_file(NULL, 0, tree_type, tree->object.sha1);
 		merged_common_ancestors = make_virtual_commit(tree, "ancestor");
 	}
 
-- 

^ permalink raw reply related

* Re: Topic descriptions
From: Robin Rosenberg @ 2006-12-07 10:45 UTC (permalink / raw)
  To: Andy Parkins; +Cc: git, Junio C Hamano
In-Reply-To: <200612070837.16412.andyparkins@gmail.com>

torsdag 07 december 2006 09:37 skrev Andy Parkins:
> On Wednesday 2006, December 06 22:31, Junio C Hamano wrote:
> > I am unlikely to use such a thing for the "What's in" message,
> > though.  The part that talks about "what the current status is"
> > is much easier to write when I need to talk about "the current";
> > otherwise I'd be forced to remember to think if I need to update
> > the information, every time I touch topic branches.
>
> It wasn't so much the what's current - as you say that would be fairly
> ridiculous as it's so fluid.  It was more a description of the topic.  I've
> got tonnes of branches where I have quickly thought of an idea and started
> work on it, only to get bored and move on.  Describing a topic in such a
> short space as "ap/short-name" is hard.

Your situation sounds similiar to mine, but I don't use regular git branches 
much. Rather I use stacked git instead. Stgit's patches can be though of as 
virtual branches. Instead of creating a dozen branches I have a dozen commits 
managed by stgit that I can choose from (and combine) easily, creating and 
destroying private "branches".


^ permalink raw reply


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