Git development
 help / color / mirror / Atom feed
* Re: best git practices, was Re: Git User's Survey 2007 unfinished summary continued
From: Peter Baumann @ 2007-10-24 21:28 UTC (permalink / raw)
  To: Andreas Ericsson
  Cc: J. Bruce Fields, Steffen Prohaska, Johannes Schindelin,
	Jakub Narebski, Federico Mena Quintero, git
In-Reply-To: <471FB3D0.4040800@op5.se>

On Wed, Oct 24, 2007 at 11:06:24PM +0200, Andreas Ericsson wrote:
> J. Bruce Fields wrote:
>> On Wed, Oct 24, 2007 at 10:12:29PM +0200, Steffen Prohaska wrote:
>>> On Oct 24, 2007, at 9:48 PM, J. Bruce Fields wrote:
>>>
>>>>> I want git pull to work like git push.
>>>> That strikes me as a less complete solution, since it only helps in the
>>>> case where the other branches all happen to be unmodified locally (hence
>>>> can be fast-forwarded).  In other cases the "git push" will still emit a
>>>> spurious error.
>>> Well, but then there's something you should really think
>>> about.
>> Perhaps, but not necessarily; you may have some branches with local
>> changes that you're content to leave unpushed (and un-updated).
>
> Sure, but that won't change. The only thing I'm proposing is that
> local copies of remote branches are automatically fast-forwarded
> on every pull, but only if
>
> * the branch has no modifications what so ever
> * the branch is set up to auto-merge with the particular branch
> fetched from the particular remote
>
> I really don't see any downsides what so ever with this. Those
> of you who do, please enlighten me.
>

You can't check what got added in your pull, e.g you can't review the new
code with something like

	gitk next..origin/next

I often do something like this, just to see what got changed. So at least
in my opinion you have to add a third point:

  * the branch has no modifications what so ever
  * the branch is set up to auto-merge with the particular branch
    fetched from the particular remote
				AND
  * the user set a config option to always autofastfoward if the above
    conditions are true! This could be implemented as a global option with
    a per branch overwrite.

Only if this option is added so a user can mark a branch to never
autofastforward (but it is still possible to  have an auto-merge config) you won't
loose valuable information.

-Peter

^ permalink raw reply

* Re: best git practices, was Re: Git User's Survey 2007 unfinished summary continued
From: Steffen Prohaska @ 2007-10-24 21:47 UTC (permalink / raw)
  To: Peter Baumann
  Cc: Andreas Ericsson, J. Bruce Fields, Johannes Schindelin,
	Jakub Narebski, Federico Mena Quintero, git
In-Reply-To: <20071024212854.GB6069@xp.machine.xx>


On Oct 24, 2007, at 11:28 PM, Peter Baumann wrote:

> On Wed, Oct 24, 2007 at 11:06:24PM +0200, Andreas Ericsson wrote:
>> J. Bruce Fields wrote:
>>> On Wed, Oct 24, 2007 at 10:12:29PM +0200, Steffen Prohaska wrote:
>>>> On Oct 24, 2007, at 9:48 PM, J. Bruce Fields wrote:
>>>>
>>>>>> I want git pull to work like git push.
>>>>> That strikes me as a less complete solution, since it only  
>>>>> helps in the
>>>>> case where the other branches all happen to be unmodified  
>>>>> locally (hence
>>>>> can be fast-forwarded).  In other cases the "git push" will  
>>>>> still emit a
>>>>> spurious error.
>>>> Well, but then there's something you should really think
>>>> about.
>>> Perhaps, but not necessarily; you may have some branches with local
>>> changes that you're content to leave unpushed (and un-updated).
>>
>> Sure, but that won't change. The only thing I'm proposing is that
>> local copies of remote branches are automatically fast-forwarded
>> on every pull, but only if
>>
>> * the branch has no modifications what so ever
>> * the branch is set up to auto-merge with the particular branch
>> fetched from the particular remote
>>
>> I really don't see any downsides what so ever with this. Those
>> of you who do, please enlighten me.
>>
>
> You can't check what got added in your pull, e.g you can't review  
> the new
> code with something like
>
> 	gitk next..origin/next

You're not forced to pull. Just use "git fetch" if you
want to do this. Or is something missing if you'd be
limited to "git fetch"?


> I often do something like this, just to see what got changed. So at  
> least
> in my opinion you have to add a third point:
>
>   * the branch has no modifications what so ever
>   * the branch is set up to auto-merge with the particular branch
>     fetched from the particular remote
> 				AND
>   * the user set a config option to always autofastfoward if the above
>     conditions are true! This could be implemented as a global  
> option with
>     a per branch overwrite.

I (and, as I understood, Andreas, too) want to change the
default. Because we believe that git would be easier to use
in workflows based on a shared repository.

But if we fail to convince the list, maybe a global
configuration variable that configures "git pull" to autoforward
branches as propose would be a nearly equally good solution.

However, I think it is dangerous to introduce many of such
configuration options. Explaining the behaviour of git will
become harder. The behaviour will become dependent on the
local configuration and eventually the first question before
answering a question will be "send me the output of 'git config
--list'. I need to see how your git is configured."

	Steffen

^ permalink raw reply

* Re: best git practices, was Re: Git User's Survey 2007 unfinished summary continued
From: Andreas Ericsson @ 2007-10-24 21:54 UTC (permalink / raw)
  To: Peter Baumann
  Cc: J. Bruce Fields, Steffen Prohaska, Johannes Schindelin,
	Jakub Narebski, Federico Mena Quintero, git
In-Reply-To: <20071024212854.GB6069@xp.machine.xx>

Peter Baumann wrote:
> On Wed, Oct 24, 2007 at 11:06:24PM +0200, Andreas Ericsson wrote:
>> J. Bruce Fields wrote:
>>> On Wed, Oct 24, 2007 at 10:12:29PM +0200, Steffen Prohaska wrote:
>>>> On Oct 24, 2007, at 9:48 PM, J. Bruce Fields wrote:
>>>>
>>>>>> I want git pull to work like git push.
>>>>> That strikes me as a less complete solution, since it only helps in the
>>>>> case where the other branches all happen to be unmodified locally (hence
>>>>> can be fast-forwarded).  In other cases the "git push" will still emit a
>>>>> spurious error.
>>>> Well, but then there's something you should really think
>>>> about.
>>> Perhaps, but not necessarily; you may have some branches with local
>>> changes that you're content to leave unpushed (and un-updated).
>> Sure, but that won't change. The only thing I'm proposing is that
>> local copies of remote branches are automatically fast-forwarded
>> on every pull, but only if
>>
>> * the branch has no modifications what so ever
>> * the branch is set up to auto-merge with the particular branch
>> fetched from the particular remote
>>
>> I really don't see any downsides what so ever with this. Those
>> of you who do, please enlighten me.
>>
> 
> You can't check what got added in your pull, e.g you can't review the new
> code with something like
> 
> 	gitk next..origin/next
> 

That's what git-fetch is for.

> I often do something like this, just to see what got changed. So at least
> in my opinion you have to add a third point:
> 
>   * the branch has no modifications what so ever
>   * the branch is set up to auto-merge with the particular branch
>     fetched from the particular remote
> 				AND
>   * the user set a config option to always autofastfoward if the above
>     conditions are true! This could be implemented as a global option with
>     a per branch overwrite.
> 

I'd be fine with that, except I think it's fairly dangerous to have
different defaults. The two first points are sort of the core of the
case I've been arguing all along.

> Only if this option is added so a user can mark a branch to never
> autofastforward (but it is still possible to  have an auto-merge config) you won't
> loose valuable information.
> 

Sure. I was thinking something along these lines:

[branch "foo"]
	remote = bar
	merge = some-branch
	autofastforward = false


Or use git-fetch. git-pull is "fetch + merge". Conceptually, I don't
think it'll be any problem what so ever telling anyone that the branches
that aren't currently checked out get merged automatically only if they
result in a fast-forward.

-- 
Andreas Ericsson                   andreas.ericsson@op5.se
OP5 AB                             www.op5.se
Tel: +46 8-230225                  Fax: +46 8-230231

^ permalink raw reply

* Feature request: Limit git-status reports to a directory
From: Michel Marti @ 2007-10-24 22:01 UTC (permalink / raw)
  To: git

I am sometimes interested in only seeing the status for a specific 
directory (and its sub-directories), but git-status is no help in this 
case - passing a directory does some sort of "git-commit --dry-run". I 
first thought that this is a bug until I saw in the man-page that this 
is actually a feature...

What I would like to have is something like "git status --limit <path>" 
and the reported filenames should then be relative to the current 
directory for easier copy/pasting them to e.g. git-add, git-diff, etc.

Cheers,

- Michel

^ permalink raw reply

* Re: best git practices, was Re: Git User's Survey 2007 unfinished summary continued
From: Johannes Schindelin @ 2007-10-24 22:14 UTC (permalink / raw)
  To: Steffen Prohaska
  Cc: Peter Baumann, Andreas Ericsson, J. Bruce Fields, Jakub Narebski,
	Federico Mena Quintero, git
In-Reply-To: <05B279A2-98A3-45F1-9661-AB361F7CAA37@zib.de>

Hi,

On Wed, 24 Oct 2007, Steffen Prohaska wrote:

> On Oct 24, 2007, at 11:28 PM, Peter Baumann wrote:
> 
> > You can't check what got added in your pull, e.g you can't review the 
> > new code with something like
> > 
> > 	gitk next..origin/next
> 
> You're not forced to pull. Just use "git fetch" if you want to do this. 
> Or is something missing if you'd be limited to "git fetch"?

I am more concerned about having very fuzzy meanings of our nomenclature. 
As of now, "pull = fetch + merge".  You want to change that, and I am sure 
that it is harder to explain, Andreas' insistence on my being wrong 
notwithstanding.

Whenever I told people "pull = fetch + merge", they got it.  Often I would 
start a talk about git by introducing distributed development.  By stating 
that working in a working directory is already forking, only without 
commiting.  Then I'd go into details, by saying that there are multiple 
repositories, and that you can update local copies of the remote branches 
by "git fetch".  And you can merge by "git merge".  And then I would write 
down on the blackboard -- the first written thing in my talk! -- pull = 
fetch + merge.

My "pupils" _always_ liked the preciseness of the nomenclature.  And they 
made many less mistakes because they had a clear mental model of what is 
remote, and what is local.  And that local branches are always forks.

> > I often do something like this, just to see what got changed. So at 
> > least in my opinion you have to add a third point:
> > 
> >  * the branch has no modifications what so ever
> >  * the branch is set up to auto-merge with the particular branch
> >    fetched from the particular remote
> > 				AND
> >  * the user set a config option to always autofastfoward if the above
> >    conditions are true! This could be implemented as a global option with
> >    a per branch overwrite.
> 
> I (and, as I understood, Andreas, too) want to change the default. 
> Because we believe that git would be easier to use in workflows based on 
> a shared repository.

And here I have to disagree strongly.  In a workflow based on a shared 
repository, you do not want to merge.  You want to rebase.  First thing 
you do when switching to another branch is fetch + rebase (that's why I 
want an option to "pull --rebase" other branches).

But _even if_ you merge instead of rebase, I fail to see how the current 
situation is different from CVS (which many people maintain is _easier_ 
than gi), where first thing you do is to "cvs update".  Just for git it is 
"git pull".

But I think I have to drive my message home again: if what you desire 
becomes reality, you take away the clear distinction between local 
and remote branches.  In fact, those branches are neither local (because 
the next pull will automatically update them with remote changes, but 
_only_ if they fast-forward) nor remote (because you plan to work on them 
locally).

But here is a proposal which should make you and your developers happy, 
_and_ should be even easier to explain:

Work with topic branches.  And when you're done, delete them.

So the beginning of the day could look like this:

	git fetch
	git checkout -b todays-topic origin/master

	[hack hack hack]
	[test test test]
	[debug debug debug]
	[occasionally commit]
	[occasionally git rebase -i origin/master]

and the end of the topic

	git branch -M master
	git push origin master

If you should not be ready to push by the end of the day, no need to 
worry.  Just stay on that topic branch, and before pushing, do

	git fetch
	git rebase origin/master

In _every_ case where I explained git, I found that people appreciated the 
two-step procedures (like you will find in the examples I showed you 
above): one git command to work locally, and one to push/fetch to/from 
origin.

Ciao,
Dscho

^ permalink raw reply

* Re: best git practices, was Re: Git User's Survey 2007 unfinished summary continued
From: Johannes Schindelin @ 2007-10-24 22:17 UTC (permalink / raw)
  To: Andreas Ericsson
  Cc: Peter Baumann, J. Bruce Fields, Steffen Prohaska, Jakub Narebski,
	Federico Mena Quintero, git
In-Reply-To: <471FBF29.8030802@op5.se>

Hi,

On Wed, 24 Oct 2007, Andreas Ericsson wrote:

> Conceptually, I don't think it'll be any problem what so ever telling 
> anyone that the branches that aren't currently checked out get merged 
> automatically only if they result in a fast-forward.

It would be a matter of seconds until someone asks "why only 
fast-forwards?  Would it not be _much_ better to merge _always_?  Stupid 
git."

And all because the concept of "local" vs "remote" was blurred.

Ciao,
Dscho

^ permalink raw reply

* Re: best git practices, was Re: Git User's Survey 2007 unfinished summary continued
From: Steffen Prohaska @ 2007-10-24 22:33 UTC (permalink / raw)
  To: Johannes Schindelin
  Cc: Peter Baumann, Andreas Ericsson, J. Bruce Fields, Jakub Narebski,
	Federico Mena Quintero, git
In-Reply-To: <Pine.LNX.4.64.0710242258201.25221@racer.site>


On Oct 25, 2007, at 12:14 AM, Johannes Schindelin wrote:

> And here I have to disagree strongly.  In a workflow based on a shared
> repository, you do not want to merge.  You want to rebase.  First  
> thing
> you do when switching to another branch is fetch + rebase (that's  
> why I
> want an option to "pull --rebase" other branches).
>
> But _even if_ you merge instead of rebase, I fail to see how the  
> current
> situation is different from CVS (which many people maintain is  
> _easier_
> than gi), where first thing you do is to "cvs update".  Just for  
> git it is
> "git pull".
>
> But I think I have to drive my message home again: if what you desire
> becomes reality, you take away the clear distinction between local
> and remote branches.  In fact, those branches are neither local  
> (because
> the next pull will automatically update them with remote changes, but
> _only_ if they fast-forward) nor remote (because you plan to work  
> on them
> locally).

Exactly, because I do not work on those branches alone. These
are _shared_ branches. I can work on such a branch with a
group of developers. I'm willing to accept this bit of chaos.

Your rebase workflow is not possible if more than one dev wants
to work on the topic branch together.

Eventually you can linearize such a topic branch using rebase.
But you need to agree first that everyone else needs to delete
the branch.



> But here is a proposal which should make you and your developers  
> happy,
> _and_ should be even easier to explain:
>
> Work with topic branches.  And when you're done, delete them.

Again, if you want to share the topic branch the situation gets
more complex.

I absolutely agree that for purely local work topic branches that
are deleted before pushing are a good solution.


> So the beginning of the day could look like this:
>
> 	git fetch
> 	git checkout -b todays-topic origin/master
>
> 	[hack hack hack]
> 	[test test test]
> 	[debug debug debug]
> 	[occasionally commit]
> 	[occasionally git rebase -i origin/master]
>
> and the end of the topic
>
> 	git branch -M master
> 	git push origin master
>
> If you should not be ready to push by the end of the day, no need to
> worry.  Just stay on that topic branch, and before pushing, do
>
> 	git fetch
> 	git rebase origin/master
>
> In _every_ case where I explained git, I found that people  
> appreciated the
> two-step procedures (like you will find in the examples I showed you
> above): one git command to work locally, and one to push/fetch to/from
> origin.

Maybe. I know git quite well now and in a shared workflow "git pull"
with auto-fast-forward would help me. I often need to run "for each
local branch: git checkout ; git merge" to get rid of the errors
reported by "git push".

	Steffen

^ permalink raw reply

* Re: best git practices, was Re: Git User's Survey 2007 unfinished summary continued
From: J. Bruce Fields @ 2007-10-24 22:38 UTC (permalink / raw)
  To: Steffen Prohaska
  Cc: Johannes Schindelin, Peter Baumann, Andreas Ericsson,
	Jakub Narebski, Federico Mena Quintero, git
In-Reply-To: <008A7EF9-6F58-47AE-9AA0-B466797F6B1D@zib.de>

On Thu, Oct 25, 2007 at 12:33:37AM +0200, Steffen Prohaska wrote:
> Maybe. I know git quite well now and in a shared workflow "git pull"
> with auto-fast-forward would help me. I often need to run "for each
> local branch: git checkout ; git merge" to get rid of the errors
> reported by "git push".

Hm.  There's gotta be more efficient ways to do that.  Maybe "git push .
origin/branch:branch" for each local "branch"?

But I'm still a little confused why you don't just want to "git push
name-of-branch" and avoid the whole problem.

--b.

^ permalink raw reply

* Re: best git practices, was Re: Git User's Survey 2007 unfinished summary continued
From: Steffen Prohaska @ 2007-10-24 22:51 UTC (permalink / raw)
  To: J. Bruce Fields
  Cc: Johannes Schindelin, Peter Baumann, Andreas Ericsson,
	Jakub Narebski, Federico Mena Quintero, git
In-Reply-To: <20071024223815.GN29830@fieldses.org>


On Oct 25, 2007, at 12:38 AM, J. Bruce Fields wrote:

> On Thu, Oct 25, 2007 at 12:33:37AM +0200, Steffen Prohaska wrote:
>> Maybe. I know git quite well now and in a shared workflow "git pull"
>> with auto-fast-forward would help me. I often need to run "for each
>> local branch: git checkout ; git merge" to get rid of the errors
>> reported by "git push".
>
> Hm.  There's gotta be more efficient ways to do that.  Maybe "git  
> push .
> origin/branch:branch" for each local "branch"?
>
> But I'm still a little confused why you don't just want to "git push
> name-of-branch" and avoid the whole problem.

There are two points:

- The current implementation of "git push" creates a remote branch
   if it does not yet exist. I want a safety net: "git push" only pushes
   if the remote branch already exists. In a sense "git push" is safer
   than "git push branch-with-typo". I use "git push branchname"
   exclusively for _creating_ new branches on the remote.

- Sometimes I updated two local branches and want to push. "git push"
   just works.

I started to believe that "git push" should always do the right
thing. Maybe it is not possible, but actually "git push" always
does the right thing for me if I ignore the error messages
about local branches that need merging. I tend to merge all
such branches right away, although it is a bit of a hassel.
Otherwise, there will be a day I'll miss an important error.

What concerns me more is how to explain the behaviour to others.
Right now, I can't tell them that "git push" just works but need
to go into a lot of details.

	Steffen

^ permalink raw reply

* Re: best git practices, was Re: Git User's Survey 2007 unfinished summary continued
From: Jakub Narebski @ 2007-10-24 23:27 UTC (permalink / raw)
  To: Karl Hasselström; +Cc: git, Catalin Marinas
In-Reply-To: <20071024113123.GB6459@diana.vm.bytemark.co.uk>

On 10/24/07, Karl Hasselström <kha@treskal.com> wrote:
> On 2007-10-24 13:04:01 +0200, Jakub Narebski wrote:
>
>> By the way, there is SRPM for StGIT in
>> http://homepage.ntlworld.com/cmarinas/stgit/ (I need it because I
>> have Python 2.4), but it is not listed on downloads page...
>
> I'll leave the webpage question to Catalin, but I'm curious about the
> Python version remark. What exactly is the problem?

If I remember correctly the StGIT RPM requires python 2.5
(and is build using python 2.5, so install with --force doesn't work).

BTW. SRPM is better than tar.gz because I can simply do "rpmbuild
--rebuild" to get binary RPM to install.

-- 
Jakub Narebski

^ permalink raw reply

* Re: best git practices, was Re: Git User's Survey 2007 unfinished summary continued
From: Johannes Schindelin @ 2007-10-24 23:28 UTC (permalink / raw)
  To: Steffen Prohaska
  Cc: Peter Baumann, Andreas Ericsson, J. Bruce Fields, Jakub Narebski,
	Federico Mena Quintero, git
In-Reply-To: <008A7EF9-6F58-47AE-9AA0-B466797F6B1D@zib.de>

Hi,

On Thu, 25 Oct 2007, Steffen Prohaska wrote:

> On Oct 25, 2007, at 12:14 AM, Johannes Schindelin wrote:
> 
> > But I think I have to drive my message home again: if what you desire 
> > becomes reality, you take away the clear distinction between local and 
> > remote branches.  In fact, those branches are neither local (because 
> > the next pull will automatically update them with remote changes, but 
> > _only_ if they fast-forward) nor remote (because you plan to work on 
> > them locally).
> 
> Exactly, because I do not work on those branches alone. These are 
> _shared_ branches. I can work on such a branch with a group of 
> developers. I'm willing to accept this bit of chaos.

It is not just a chaos.  I see a serious problem here.  On _your_ 
computer, you do _not_ have a shared branch.  Which is visible _even_ in 
your modified work flow when you have unpushed changes.

So your desired illusion that your local branches are anything but local 
branches will never be perfect enough.

> Your rebase workflow is not possible if more than one dev wants to work 
> on the topic branch together.

Why not?  I do it all the time.  CVS users do it all the time, for that 
matter.

> Eventually you can linearize such a topic branch using rebase. But you 
> need to agree first that everyone else needs to delete the branch.

No, you can linearize your branch already while cleaning up your local 
branch before continuing to work on the topic.

> > But here is a proposal which should make you and your developers 
> > happy, _and_ should be even easier to explain:
> > 
> > Work with topic branches.  And when you're done, delete them.
> 
> Again, if you want to share the topic branch the situation gets
> more complex.

Hardly so.  In my proposed solution to your problem, there is nothing 
which prevents you from working off of another branch than "master".

> > So the beginning of the day could look like this:
> > 
> > 	git fetch
> > 	git checkout -b todays-topic origin/master
> > 
> > 	[hack hack hack]
> > 	[test test test]
> > 	[debug debug debug]
> > 	[occasionally commit]
> > 	[occasionally git rebase -i origin/master]
> > 
> > and the end of the topic
> > 
> > 	git branch -M master
> > 	git push origin master
> > 
> > If you should not be ready to push by the end of the day, no need to
> > worry.  Just stay on that topic branch, and before pushing, do
> > 
> > 	git fetch
> > 	git rebase origin/master
> > 
> > In _every_ case where I explained git, I found that people appreciated the
> > two-step procedures (like you will find in the examples I showed you
> > above): one git command to work locally, and one to push/fetch to/from
> > origin.
> 
> Maybe. I know git quite well now and in a shared workflow "git pull"
> with auto-fast-forward would help me. I often need to run "for each
> local branch: git checkout ; git merge" to get rid of the errors
> reported by "git push".

The problem I see here: you know git quite well.  Others don't, and will 
be mightily confused why pull updates local branches sometimes, and 
sometimes not.

Ciao,
Dscho

^ permalink raw reply

* [PATCH] git-cvsimport: Add -N option to force a new import
From: Matt McCutchen @ 2007-10-24 23:28 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

I had a git repository for development of rsync and wanted to start
importing the upstream CVS with git-cvsimport, but git-cvsimport saw
that the git repository existed and insisted on updating a previous
import.  This patch adds an -N option to git-cvsimport to force a new
import and updates the documentation appropriately.

Signed-off-by: Matt McCutchen <matt@mattmccutchen.net>
---
I implemented this because I needed it; adopt it in the main git if you
like it.

 Documentation/git-cvsimport.txt |    5 ++++-
 git-cvsimport.perl              |    9 ++++++---
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/Documentation/git-cvsimport.txt b/Documentation/git-cvsimport.txt
index fdd7ec7..f595957 100644
--- a/Documentation/git-cvsimport.txt
+++ b/Documentation/git-cvsimport.txt
@@ -13,7 +13,7 @@ SYNOPSIS
 	      [-A <author-conv-file>] [-p <options-for-cvsps>] [-P <file>]
 	      [-C <git_repository>] [-z <fuzz>] [-i] [-k] [-u] [-s <subst>]
 	      [-a] [-m] [-M <regex>] [-S <regex>] [-L <commitlimit>]
-	      [-r <remote>] [<CVS_module>]
+	      [-r <remote>] [-N] [<CVS_module>]
 

 DESCRIPTION
@@ -144,6 +144,9 @@ It is not recommended to use this feature if you intend to
 export changes back to CVS again later with
 gitlink:git-cvsexportcommit[1].
 
+-N::
+	Do a new import even if the git repository already exists.
+
 -h::
 	Print a short usage message and exit.
 
diff --git a/git-cvsimport.perl b/git-cvsimport.perl
index 2954fb8..6f03be9 100755
--- a/git-cvsimport.perl
+++ b/git-cvsimport.perl
@@ -29,7 +29,7 @@ use IPC::Open2;
 $SIG{'PIPE'}="IGNORE";
 $ENV{'TZ'}="UTC";
 
-our ($opt_h,$opt_o,$opt_v,$opt_k,$opt_u,$opt_d,$opt_p,$opt_C,$opt_z,$opt_i,$opt_P, $opt_s,$opt_m,$opt_M,$opt_A,$opt_S,$opt_L, $opt_a, $opt_r);
+our ($opt_h,$opt_o,$opt_v,$opt_k,$opt_u,$opt_d,$opt_p,$opt_C,$opt_z,$opt_i,$opt_P, $opt_s,$opt_m,$opt_M,$opt_A,$opt_S,$opt_L, $opt_a, $opt_r, $opt_N);
 my (%conv_author_name, %conv_author_email);
 
 sub usage(;$) {
@@ -40,7 +40,7 @@ Usage: ${\basename $0}     # fetch/update GIT from CVS
        [-o branch-for-HEAD] [-h] [-v] [-d CVSROOT] [-A author-conv-file]
        [-p opts-for-cvsps] [-P file] [-C GIT_repository] [-z fuzz] [-i] [-k]
        [-u] [-s subst] [-a] [-m] [-M regex] [-S regex] [-L commitlimit]
-       [-r remote] [CVS_module]
+       [-r remote] [-N] [CVS_module]
 END
 	exit(1);
 }
@@ -114,7 +114,7 @@ sub read_repo_config {
     }
 }
 
-my $opts = "haivmkuo:d:p:r:C:z:s:M:P:A:S:L:";
+my $opts = "haivmkuNo:d:p:r:C:z:s:M:P:A:S:L:";
 read_repo_config($opts);
 getopts($opts) or usage();
 usage if $opt_h;
@@ -563,7 +563,10 @@ unless (-d $git_dir) {
 	die "Cannot init the GIT db at $git_tree: $?\n" if $?;
 	system("git-read-tree");
 	die "Cannot init an empty tree: $?\n" if $?;
+	$opt_N = 1;
+}
 
+if ($opt_N) {
 	$last_branch = $opt_o;
 	$orig_branch = "";
 } else {
-- 
1.5.3.3.128.g56927

^ permalink raw reply related

* Re: best git practices, was Re: Git User's Survey 2007 unfinished summary continued
From: Jakub Narebski @ 2007-10-24 23:48 UTC (permalink / raw)
  To: Andreas Ericsson
  Cc: J. Bruce Fields, Steffen Prohaska, Johannes Schindelin,
	Federico Mena Quintero, git
In-Reply-To: <471F9FD1.6080002@op5.se>

On 10/24/07, Andreas Ericsson <ae@op5.se> wrote:

> git pull. Not git push. git pull operates on one working branch
> at a time (by default), whereas git push uploads and fast-forwards
> all the common branches (by default). I want git pull to work like
> git push.

git push is opposite (almost) to git fetch, not to git pull.

-- 
Jakub Narebski

^ permalink raw reply

* Re: What's cooking in git.git (topics)
From: Scott Parish @ 2007-10-25  0:35 UTC (permalink / raw)
  To: Andreas Ericsson; +Cc: Junio C Hamano, git
In-Reply-To: <471F8EA0.9030902@op5.se>

On Wed, Oct 24, 2007 at 08:27:44PM +0200, Andreas Ericsson wrote:

> > Should i resend my string of patches? I've seen people numbering
> > their patches, should i do that as well?
> 
>  'git format-patch -n' will do it for you. I take it you've found
>  out about git-send-email already?

I actually hadn't seen either of those. Thanks!

sRp

-- 
Scott Parish
http://srparish.net/

^ permalink raw reply

* Re: git-remote: Use of uninitialized value in string ne, line 248
From: Junio C Hamano @ 2007-10-25  1:48 UTC (permalink / raw)
  To: Alex Riesen; +Cc: git discussion list, Martin F Krafft
In-Reply-To: <20071024193954.GA5280@steel.home>

Alex Riesen <raa.lkml@gmail.com> writes:

> Junio C Hamano, Wed, Oct 24, 2007 13:49:51 +0200:
>> Perhaps....
>> 
>>  git-remote.perl |    3 ++-
>>  1 files changed, 2 insertions(+), 1 deletions(-)
>> 
>> diff --git a/git-remote.perl b/git-remote.perl
>> index 9ca3e7e..4cee044 100755
>> --- a/git-remote.perl
>> +++ b/git-remote.perl
>> @@ -244,7 +244,8 @@ sub show_remote {
>>  	print "* remote $name\n";
>>  	print "  URL: $info->{'URL'}\n";
>>  	for my $branchname (sort keys %$branch) {
>> -		next if ($branch->{$branchname}{'REMOTE'} ne $name);
>> +		next if (!$branch->{$branchname}{'REMOTE'} ||
>
> just you never call yor branches "0".

Ok, that is about remote name '0' but whatever...

-- >8 --
[PATCH] git-remote: fix "Use of uninitialized value in string ne"

martin f krafft <madduck@madduck.net> writes:

> piper:~> git remote show origin
> * remote origin
>   URL: ssh://git.madduck.net/~/git/etc/mailplate.git
> Use of uninitialized value in string ne at /usr/local/stow/git/bin/git-remote line 248.

This is because there might not be branch.<name>.remote defined but
the code unconditionally dereferences $branch->{$name}{'REMOTE'} and
compares with another string.

Tested-by: Martin F Krafft <madduck@madduck.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 git-remote.perl |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/git-remote.perl b/git-remote.perl
index 8e2dc4d..11630b1 100755
--- a/git-remote.perl
+++ b/git-remote.perl
@@ -244,7 +244,8 @@ sub show_remote {
 	print "* remote $name\n";
 	print "  URL: $info->{'URL'}\n";
 	for my $branchname (sort keys %$branch) {
-		next if ($branch->{$branchname}{'REMOTE'} ne $name);
+		next unless (defined $branch->{$branchname}{'REMOTE'} &&
+			     $branch->{$branchname}{'REMOTE'} eq $name);
 		my @merged = map {
 			s|^refs/heads/||;
 			$_;
-- 
1.5.3.4.1324.ga7925

^ permalink raw reply related

* Re: Feature request: Limit git-status reports to a directory
From: Yin Ping @ 2007-10-25  2:14 UTC (permalink / raw)
  To: Michel Marti; +Cc: git
In-Reply-To: <ffofbm$lmc$1@ger.gmane.org>

On 10/25/07, Michel Marti <mma@objectxp.com> wrote:
> I am sometimes interested in only seeing the status for a specific
> directory (and its sub-directories), but git-status is no help in this
> case - passing a directory does some sort of "git-commit --dry-run". I
> first thought that this is a bug until I saw in the man-page that this
> is actually a feature...
It's also painful for me. IMHO, the behaviour of "git-status" should
keep consistent with "git-diff" and "git-log" which allow for the
path.

Another point, It will be helpful to add a config item to change the
default behaviour for 'git-diff" and "git-log". For example,
'diff.defaultcurrentpath=true' to let git only show difference in
current directory instead of difference in top directory when typing
'git-diff'
>
> - Michel
>
> -
> 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
>


-- 
franky

^ permalink raw reply

* Re: [PATCH] git-cvsimport: Add -N option to force a new import
From: Junio C Hamano @ 2007-10-25  3:17 UTC (permalink / raw)
  To: Matt McCutchen; +Cc: git
In-Reply-To: <1193268519.8008.11.camel@mattlaptop2>

Matt McCutchen <matt@mattmccutchen.net> writes:

> I had a git repository for development of rsync and wanted to start
> importing the upstream CVS with git-cvsimport, but git-cvsimport saw
> that the git repository existed and insisted on updating a previous
> import.  This patch adds an -N option to git-cvsimport to force a new
> import and updates the documentation appropriately.

Sounds like a useful addition.  Tests?

^ permalink raw reply

* [PATCH 1/7] "git" calls help_unknown_cmd(""); "git help" and "git help -a" return 0
From: Scott R Parish @ 2007-10-25  3:37 UTC (permalink / raw)
  To: git; +Cc: Scott R Parish

Signed-off-by: Scott R Parish <srp@srparish.net>
---
 git.c  |    5 ++---
 help.c |    4 ++--
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/git.c b/git.c
index 853e66c..e1c99e3 100644
--- a/git.c
+++ b/git.c
@@ -445,9 +445,8 @@ int main(int argc, const char **argv)
 		if (!prefixcmp(argv[0], "--"))
 			argv[0] += 2;
 	} else {
-		/* Default command: "help" */
-		argv[0] = "help";
-		argc = 1;
+		/* The user didn't specify a command; give them help */
+		help_unknown_cmd("");
 	}
 	cmd = argv[0];
 
diff --git a/help.c b/help.c
index 1cd33ec..b0d2dd4 100644
--- a/help.c
+++ b/help.c
@@ -204,14 +204,14 @@ int cmd_help(int argc, const char **argv, const char *prefix)
 	if (!help_cmd) {
 		printf("usage: %s\n\n", git_usage_string);
 		list_common_cmds_help();
-		exit(1);
+		exit(0);
 	}
 
 	else if (!strcmp(help_cmd, "--all") || !strcmp(help_cmd, "-a")) {
 		printf("usage: %s\n\n", git_usage_string);
 		if(exec_path)
 			list_commands(exec_path, "git-*");
-		exit(1);
+		exit(0);
 	}
 
 	else
-- 
gitgui.0.8.4.11176.gd9205-dirty

^ permalink raw reply related

* [PATCH 6/7] walk PATH to generate list of commands for "help -a"
From: Scott R Parish @ 2007-10-25  3:37 UTC (permalink / raw)
  To: git; +Cc: Scott R Parish
In-Reply-To: <1193283437-1706-5-git-send-email-srp@srparish.net>

Signed-off-by: Scott R Parish <srp@srparish.net>
---
 help.c |   69 ++++++++++++++++++++++++++++++++++++++++++++++++---------------
 1 files changed, 52 insertions(+), 17 deletions(-)

diff --git a/help.c b/help.c
index 906f8f6..3f8b4aa 100644
--- a/help.c
+++ b/help.c
@@ -64,6 +64,19 @@ static int cmdname_compare(const void *a_, const void *b_)
 	return strcmp(a->name, b->name);
 }
 
+static void uniq(struct cmdname **cmdname)
+{
+	int i, j;
+
+	for (i = j = 1; i < cmdname_cnt; i++) {
+		if (strcmp(cmdname[i]->name, cmdname[i-1]->name)) {
+			cmdname[j++] = cmdname[i];
+		}
+	}
+
+	cmdname_cnt = j;
+}
+
 static void pretty_print_string_list(struct cmdname **cmdname, int longest)
 {
 	int cols = 1, rows;
@@ -71,12 +84,13 @@ static void pretty_print_string_list(struct cmdname **cmdname, int longest)
 	int max_cols = term_columns() - 1; /* don't print *on* the edge */
 	int i, j;
 
+	qsort(cmdname, cmdname_cnt, sizeof(*cmdname), cmdname_compare);
+	uniq(cmdname);
+
 	if (space < max_cols)
 		cols = max_cols / space;
 	rows = (cmdname_cnt + cols - 1) / cols;
 
-	qsort(cmdname, cmdname_cnt, sizeof(*cmdname), cmdname_compare);
-
 	for (i = 0; i < rows; i++) {
 		printf("  ");
 
@@ -93,19 +107,17 @@ static void pretty_print_string_list(struct cmdname **cmdname, int longest)
 	}
 }
 
-static void list_commands(const char *exec_path, const char *prefix)
+static unsigned int list_commands_in_dir(const char *dir, const char *prefix)
 {
 	unsigned int longest = 0;
 	int prefix_len = strlen(prefix);
-	DIR *dir = opendir(exec_path);
+	DIR *dirp = opendir(dir);
 	struct dirent *de;
 
-	if (!dir || chdir(exec_path)) {
-		fprintf(stderr, "git: '%s': %s\n", exec_path, strerror(errno));
-		exit(1);
-	}
+	if (!dirp || chdir(dir))
+		return 0;
 
-	while ((de = readdir(dir)) != NULL) {
+	while ((de = readdir(dirp)) != NULL) {
 		struct stat st;
 		int entlen;
 
@@ -126,12 +138,37 @@ static void list_commands(const char *exec_path, const char *prefix)
 
 		add_cmdname(de->d_name + prefix_len, entlen);
 	}
-	closedir(dir);
+	closedir(dirp);
 
-	printf("git commands available in '%s'\n", exec_path);
-	printf("----------------------------");
-	mput_char('-', strlen(exec_path));
-	putchar('\n');
+	return longest;
+}
+
+static void list_commands(const char *prefix)
+{
+	unsigned int longest = 0;
+	unsigned int len;
+	const char *env_path = getenv("PATH");
+	char *paths, *path, *colon;
+
+	if (!env_path) {
+		fprintf(stderr, "PATH not set\n");
+		exit(1);
+	}
+
+	path = paths = xstrdup(env_path);
+	while ((char *)1 != path) {
+		if ((colon = strchr(path, ':')))
+			*colon = 0;
+
+		len = list_commands_in_dir(path, prefix);
+		longest = MAX(longest, len);
+
+		path = colon + 1;
+	}
+	free(paths);
+
+	printf("available git commands\n");
+	printf("----------------------\n");
 	pretty_print_string_list(cmdname, longest);
 	putchar('\n');
 }
@@ -188,7 +225,6 @@ int cmd_version(int argc, const char **argv, const char *prefix)
 int cmd_help(int argc, const char **argv, const char *prefix)
 {
 	const char *help_cmd = argc > 1 ? argv[1] : NULL;
-	const char *exec_path = git_exec_path();
 
 	if (!help_cmd) {
 		printf("usage: %s\n\n", git_usage_string);
@@ -198,8 +234,7 @@ int cmd_help(int argc, const char **argv, const char *prefix)
 
 	else if (!strcmp(help_cmd, "--all") || !strcmp(help_cmd, "-a")) {
 		printf("usage: %s\n\n", git_usage_string);
-		if(exec_path)
-			list_commands(exec_path, "git-");
+		list_commands("git-");
 		exit(0);
 	}
 
-- 
gitgui.0.8.4.11176.gd9205-dirty

^ permalink raw reply related

* [PATCH 2/7] s/pattern/prefix/ in help's list_commands
From: Scott R Parish @ 2007-10-25  3:37 UTC (permalink / raw)
  To: git; +Cc: Scott R Parish
In-Reply-To: <1193283437-1706-1-git-send-email-srp@srparish.net>

list_commands() currently accepts and ignores a "pattern" argument,
and then hard codes a prefix as well as some magic numbers. This
renames the arg from pattern to prefix and uses that instead of the
hardcoded stuff.

Signed-off-by: Scott R Parish <srp@srparish.net>
---
 help.c |   13 +++++++------
 1 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/help.c b/help.c
index b0d2dd4..950f62d 100644
--- a/help.c
+++ b/help.c
@@ -93,11 +93,12 @@ static void pretty_print_string_list(struct cmdname **cmdname, int longest)
 	}
 }
 
-static void list_commands(const char *exec_path, const char *pattern)
+static void list_commands(const char *exec_path, const char *prefix)
 {
 	unsigned int longest = 0;
 	char path[PATH_MAX];
 	int dirlen;
+	int prefix_len = strlen(prefix);
 	DIR *dir = opendir(exec_path);
 	struct dirent *de;
 
@@ -120,7 +121,7 @@ static void list_commands(const char *exec_path, const char *pattern)
 		struct stat st;
 		int entlen;
 
-		if (prefixcmp(de->d_name, "git-"))
+		if (prefixcmp(de->d_name, prefix))
 			continue;
 		strcpy(path+dirlen, de->d_name);
 		if (stat(path, &st) || /* stat, not lstat */
@@ -128,14 +129,14 @@ static void list_commands(const char *exec_path, const char *pattern)
 		    !(st.st_mode & S_IXUSR))
 			continue;
 
-		entlen = strlen(de->d_name);
+		entlen = strlen(de->d_name) - prefix_len;
 		if (has_extension(de->d_name, ".exe"))
 			entlen -= 4;
 
 		if (longest < entlen)
 			longest = entlen;
 
-		add_cmdname(de->d_name + 4, entlen-4);
+		add_cmdname(de->d_name + prefix_len, entlen);
 	}
 	closedir(dir);
 
@@ -143,7 +144,7 @@ static void list_commands(const char *exec_path, const char *pattern)
 	printf("----------------------------");
 	mput_char('-', strlen(exec_path));
 	putchar('\n');
-	pretty_print_string_list(cmdname, longest - 4);
+	pretty_print_string_list(cmdname, longest);
 	putchar('\n');
 }
 
@@ -210,7 +211,7 @@ int cmd_help(int argc, const char **argv, const char *prefix)
 	else if (!strcmp(help_cmd, "--all") || !strcmp(help_cmd, "-a")) {
 		printf("usage: %s\n\n", git_usage_string);
 		if(exec_path)
-			list_commands(exec_path, "git-*");
+			list_commands(exec_path, "git-");
 		exit(0);
 	}
 
-- 
gitgui.0.8.4.11176.gd9205-dirty

^ permalink raw reply related

* [PATCH 3/7] "current_exec_path" is a misleading name, use "argv_exec_path" Signed-off-by: Scott R Parish <srp@srparish.net>
From: Scott R Parish @ 2007-10-25  3:37 UTC (permalink / raw)
  To: git; +Cc: Scott R Parish
In-Reply-To: <1193283437-1706-2-git-send-email-srp@srparish.net>

---
 exec_cmd.c |   12 ++++++------
 exec_cmd.h |    2 +-
 git.c      |    2 +-
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/exec_cmd.c b/exec_cmd.c
index 9b74ed2..8b681d0 100644
--- a/exec_cmd.c
+++ b/exec_cmd.c
@@ -5,11 +5,11 @@
 
 extern char **environ;
 static const char *builtin_exec_path = GIT_EXEC_PATH;
-static const char *current_exec_path;
+static const char *argv_exec_path = 0;
 
-void git_set_exec_path(const char *exec_path)
+void git_set_argv_exec_path(const char *exec_path)
 {
-	current_exec_path = exec_path;
+	argv_exec_path = exec_path;
 }
 
 
@@ -18,8 +18,8 @@ const char *git_exec_path(void)
 {
 	const char *env;
 
-	if (current_exec_path)
-		return current_exec_path;
+	if (argv_exec_path)
+		return argv_exec_path;
 
 	env = getenv(EXEC_PATH_ENVIRONMENT);
 	if (env && *env) {
@@ -34,7 +34,7 @@ int execv_git_cmd(const char **argv)
 {
 	char git_command[PATH_MAX + 1];
 	int i;
-	const char *paths[] = { current_exec_path,
+	const char *paths[] = { argv_exec_path,
 				getenv(EXEC_PATH_ENVIRONMENT),
 				builtin_exec_path };
 
diff --git a/exec_cmd.h b/exec_cmd.h
index 849a839..da99287 100644
--- a/exec_cmd.h
+++ b/exec_cmd.h
@@ -1,7 +1,7 @@
 #ifndef GIT_EXEC_CMD_H
 #define GIT_EXEC_CMD_H
 
-extern void git_set_exec_path(const char *exec_path);
+extern void git_set_argv_exec_path(const char *exec_path);
 extern const char* git_exec_path(void);
 extern int execv_git_cmd(const char **argv); /* NULL terminated */
 extern int execl_git_cmd(const char *cmd, ...);
diff --git a/git.c b/git.c
index e1c99e3..f659338 100644
--- a/git.c
+++ b/git.c
@@ -51,7 +51,7 @@ static int handle_options(const char*** argv, int* argc, int* envchanged)
 		if (!prefixcmp(cmd, "--exec-path")) {
 			cmd += 11;
 			if (*cmd == '=')
-				git_set_exec_path(cmd + 1);
+				git_set_argv_exec_path(cmd + 1);
 			else {
 				puts(git_exec_path());
 				exit(0);
-- 
gitgui.0.8.4.11176.gd9205-dirty

^ permalink raw reply related

* [PATCH 4/7] use only the PATH for exec'ing git commands
From: Scott R Parish @ 2007-10-25  3:37 UTC (permalink / raw)
  To: git; +Cc: Scott R Parish
In-Reply-To: <1193283437-1706-3-git-send-email-srp@srparish.net>

We need to correctly set up PATH for non-c based git commands. Since we
already do this, we can just use that PATH and execvp, instead of looping
over the paths with execve.

This patch adds a setup_path() function to exec_cmd.c, which sets
the PATH order correctly for our search order. execv_git_cmd() is
stripped down to setting up argv and calling execvp(). git.c's main()
only only needs to call setup_path().

Signed-off-by: Scott R Parish <srp@srparish.net>
---
 exec_cmd.c |  121 ++++++++++++++++++++++++++----------------------------------
 exec_cmd.h |    1 +
 git.c      |   43 +++------------------
 3 files changed, 60 insertions(+), 105 deletions(-)

diff --git a/exec_cmd.c b/exec_cmd.c
index 8b681d0..c228dbf 100644
--- a/exec_cmd.c
+++ b/exec_cmd.c
@@ -29,85 +29,68 @@ const char *git_exec_path(void)
 	return builtin_exec_path;
 }
 
+static void add_path(struct strbuf *out, const char *path)
+{
+	if (path && strlen(path)) {
+		if (is_absolute_path(path))
+			strbuf_addstr(out, path);
+		else
+			strbuf_addstr(out, make_absolute_path(path));
+
+		strbuf_addch(out, ':');
+	}
+}
+
+void setup_path(const char *cmd_path)
+{
+	const char *old_path = getenv("PATH");
+	struct strbuf new_path;
+
+	strbuf_init(&new_path, 0);
+
+	add_path(&new_path, argv_exec_path);
+	add_path(&new_path, getenv(EXEC_PATH_ENVIRONMENT));
+	add_path(&new_path, builtin_exec_path);
+	add_path(&new_path, cmd_path);
+
+	if (old_path)
+		strbuf_addstr(&new_path, old_path);
+	else
+		strbuf_addstr(&new_path, "/usr/local/bin:/usr/bin:/bin");
+
+	setenv("PATH", new_path.buf, 1);
+
+	strbuf_release(&new_path);
+}
 
 int execv_git_cmd(const char **argv)
 {
-	char git_command[PATH_MAX + 1];
-	int i;
-	const char *paths[] = { argv_exec_path,
-				getenv(EXEC_PATH_ENVIRONMENT),
-				builtin_exec_path };
-
-	for (i = 0; i < ARRAY_SIZE(paths); ++i) {
-		size_t len;
-		int rc;
-		const char *exec_dir = paths[i];
-		const char *tmp;
-
-		if (!exec_dir || !*exec_dir) continue;
-
-		if (*exec_dir != '/') {
-			if (!getcwd(git_command, sizeof(git_command))) {
-				fprintf(stderr, "git: cannot determine "
-					"current directory: %s\n",
-					strerror(errno));
-				break;
-			}
-			len = strlen(git_command);
-
-			/* Trivial cleanup */
-			while (!prefixcmp(exec_dir, "./")) {
-				exec_dir += 2;
-				while (*exec_dir == '/')
-					exec_dir++;
-			}
-
-			rc = snprintf(git_command + len,
-				      sizeof(git_command) - len, "/%s",
-				      exec_dir);
-			if (rc < 0 || rc >= sizeof(git_command) - len) {
-				fprintf(stderr, "git: command name given "
-					"is too long.\n");
-				break;
-			}
-		} else {
-			if (strlen(exec_dir) + 1 > sizeof(git_command)) {
-				fprintf(stderr, "git: command name given "
-					"is too long.\n");
-				break;
-			}
-			strcpy(git_command, exec_dir);
-		}
-
-		len = strlen(git_command);
-		rc = snprintf(git_command + len, sizeof(git_command) - len,
-			      "/git-%s", argv[0]);
-		if (rc < 0 || rc >= sizeof(git_command) - len) {
-			fprintf(stderr,
-				"git: command name given is too long.\n");
-			break;
-		}
+	struct strbuf cmd;
+	const char *tmp;
 
-		/* argv[0] must be the git command, but the argv array
-		 * belongs to the caller, and my be reused in
-		 * subsequent loop iterations. Save argv[0] and
-		 * restore it on error.
-		 */
+	strbuf_init(&cmd, 0);
+	strbuf_addf(&cmd, "git-%s", argv[0]);
 
-		tmp = argv[0];
-		argv[0] = git_command;
+	/* argv[0] must be the git command, but the argv array
+	 * belongs to the caller, and my be reused in
+	 * subsequent loop iterations. Save argv[0] and
+	 * restore it on error.
+	 */
+	tmp = argv[0];
+	argv[0] = cmd.buf;
 
-		trace_argv_printf(argv, -1, "trace: exec:");
+	trace_argv_printf(argv, -1, "trace: exec:");
 
-		/* execve() can only ever return if it fails */
-		execve(git_command, (char **)argv, environ);
+	/* execvp() can only ever return if it fails */
+	execvp(cmd.buf, (char **)argv);
 
-		trace_printf("trace: exec failed: %s\n", strerror(errno));
+	trace_printf("trace: exec failed: %s\n", strerror(errno));
 
-		argv[0] = tmp;
-	}
-	return -1;
+	argv[0] = tmp;
 
+	strbuf_release(&cmd);
+
+	return -1;
 }
 
 
diff --git a/exec_cmd.h b/exec_cmd.h
index da99287..a892355 100644
--- a/exec_cmd.h
+++ b/exec_cmd.h
@@ -3,6 +3,7 @@
 
 extern void git_set_argv_exec_path(const char *exec_path);
 extern const char* git_exec_path(void);
+extern void setup_path(const char *);
 extern int execv_git_cmd(const char **argv); /* NULL terminated */
 extern int execl_git_cmd(const char *cmd, ...);
 
diff --git a/git.c b/git.c
index f659338..a639e42 100644
--- a/git.c
+++ b/git.c
@@ -6,28 +6,6 @@
 const char git_usage_string[] =
 	"git [--version] [--exec-path[=GIT_EXEC_PATH]] [-p|--paginate|--no-pager] [--bare] [--git-dir=GIT_DIR] [--work-tree=GIT_WORK_TREE] [--help] COMMAND [ARGS]";
 
-static void prepend_to_path(const char *dir, int len)
-{
-	const char *old_path = getenv("PATH");
-	char *path;
-	int path_len = len;
-
-	if (!old_path)
-		old_path = "/usr/local/bin:/usr/bin:/bin";
-
-	path_len = len + strlen(old_path) + 1;
-
-	path = xmalloc(path_len + 1);
-
-	memcpy(path, dir, len);
-	path[len] = ':';
-	memcpy(path + len + 1, old_path, path_len - len);
-
-	setenv("PATH", path, 1);
-
-	free(path);
-}
-
 static int handle_options(const char*** argv, int* argc, int* envchanged)
 {
 	int handled = 0;
@@ -403,7 +381,7 @@ int main(int argc, const char **argv)
 {
 	const char *cmd = argv[0] ? argv[0] : "git-help";
 	char *slash = strrchr(cmd, '/');
-	const char *exec_path = NULL;
+	const char *cmd_path = NULL;
 	int done_alias = 0;
 
 	/*
@@ -413,10 +391,7 @@ int main(int argc, const char **argv)
 	 */
 	if (slash) {
 		*slash++ = 0;
-		if (*cmd == '/')
-			exec_path = cmd;
-		else
-			exec_path = xstrdup(make_absolute_path(cmd));
+		cmd_path = cmd;
 		cmd = slash;
 	}
 
@@ -451,16 +426,12 @@ int main(int argc, const char **argv)
 	cmd = argv[0];
 
 	/*
-	 * We execute external git command via execv_git_cmd(),
-	 * which looks at "--exec-path" option, GIT_EXEC_PATH
-	 * environment, and $(gitexecdir) in Makefile while built,
-	 * in this order.  For scripted commands, we prepend
-	 * the value of the exec_path variable to the PATH.
+	 * We use PATH to find git commands, but we prepend some higher
+	 * precidence paths: the "--exec-path" option, the GIT_EXEC_PATH
+	 * environment, and the $(gitexecdir) from the Makefile at build
+	 * time.
 	 */
-	if (exec_path)
-		prepend_to_path(exec_path, strlen(exec_path));
-	exec_path = git_exec_path();
-	prepend_to_path(exec_path, strlen(exec_path));
+	setup_path(cmd_path);
 
 	while (1) {
 		/* See if it's an internal command */
-- 
gitgui.0.8.4.11176.gd9205-dirty

^ permalink raw reply related

* [PATCH 5/7] chdir() into list_commands() dir instead of building paths for stat()
From: Scott R Parish @ 2007-10-25  3:37 UTC (permalink / raw)
  To: git; +Cc: Scott R Parish
In-Reply-To: <1193283437-1706-4-git-send-email-srp@srparish.net>

Signed-off-by: Scott R Parish <srp@srparish.net>
---
 help.c |   18 +++---------------
 1 files changed, 3 insertions(+), 15 deletions(-)

diff --git a/help.c b/help.c
index 950f62d..906f8f6 100644
--- a/help.c
+++ b/help.c
@@ -96,35 +96,23 @@ static void pretty_print_string_list(struct cmdname **cmdname, int longest)
 static void list_commands(const char *exec_path, const char *prefix)
 {
 	unsigned int longest = 0;
-	char path[PATH_MAX];
-	int dirlen;
 	int prefix_len = strlen(prefix);
 	DIR *dir = opendir(exec_path);
 	struct dirent *de;
 
-	if (!dir) {
+	if (!dir || chdir(exec_path)) {
 		fprintf(stderr, "git: '%s': %s\n", exec_path, strerror(errno));
 		exit(1);
 	}
 
-	dirlen = strlen(exec_path);
-	if (PATH_MAX - 20 < dirlen) {
-		fprintf(stderr, "git: insanely long exec-path '%s'\n",
-			exec_path);
-		exit(1);
-	}
-
-	memcpy(path, exec_path, dirlen);
-	path[dirlen++] = '/';
-
 	while ((de = readdir(dir)) != NULL) {
 		struct stat st;
 		int entlen;
 
 		if (prefixcmp(de->d_name, prefix))
 			continue;
-		strcpy(path+dirlen, de->d_name);
-		if (stat(path, &st) || /* stat, not lstat */
+
+		if (stat(de->d_name, &st) || /* stat, not lstat */
 		    !S_ISREG(st.st_mode) ||
 		    !(st.st_mode & S_IXUSR))
 			continue;
-- 
gitgui.0.8.4.11176.gd9205-dirty

^ permalink raw reply related

* [PATCH 7/7] shell should call setup_path() instead of manually setting up its path
From: Scott R Parish @ 2007-10-25  3:44 UTC (permalink / raw)
  To: git; +Cc: Scott R Parish

Signed-off-by: Scott R Parish <srp@srparish.net>
---
 shell.c |    8 +-------
 1 files changed, 1 insertions(+), 7 deletions(-)

diff --git a/shell.c b/shell.c
index cfe372b..9826109 100644
--- a/shell.c
+++ b/shell.c
@@ -24,17 +24,11 @@ static int do_cvs_cmd(const char *me, char *arg)
 	const char *cvsserver_argv[3] = {
 		"cvsserver", "server", NULL
 	};
-	const char *oldpath = getenv("PATH");
-	struct strbuf newpath = STRBUF_INIT;
 
 	if (!arg || strcmp(arg, "server"))
 		die("git-cvsserver only handles server: %s", arg);
 
-	strbuf_addstr(&newpath, git_exec_path());
-	strbuf_addch(&newpath, ':');
-	strbuf_addstr(&newpath, oldpath);
-
-	setenv("PATH", strbuf_detach(&newpath, NULL), 1);
+	setup_path(NULL);
 
 	return execv_git_cmd(cvsserver_argv);
 }
-- 
gitgui.0.8.4.11176.gd9205-dirty

^ permalink raw reply related

* [PATCH 7/7] shell should call setup_path() instead of manually setting up its path
From: Scott R Parish @ 2007-10-25  3:37 UTC (permalink / raw)
  To: git; +Cc: Scott R Parish
In-Reply-To: <1193283437-1706-6-git-send-email-srp@srparish.net>

Signed-off-by: Scott R Parish <srp@srparish.net>
---
 shell.c |    8 +-------
 1 files changed, 1 insertions(+), 7 deletions(-)

diff --git a/shell.c b/shell.c
index cfe372b..9826109 100644
--- a/shell.c
+++ b/shell.c
@@ -24,17 +24,11 @@ static int do_cvs_cmd(const char *me, char *arg)
 	const char *cvsserver_argv[3] = {
 		"cvsserver", "server", NULL
 	};
-	const char *oldpath = getenv("PATH");
-	struct strbuf newpath = STRBUF_INIT;
 
 	if (!arg || strcmp(arg, "server"))
 		die("git-cvsserver only handles server: %s", arg);
 
-	strbuf_addstr(&newpath, git_exec_path());
-	strbuf_addch(&newpath, ':');
-	strbuf_addstr(&newpath, oldpath);
-
-	setenv("PATH", strbuf_detach(&newpath, NULL), 1);
+	setup_path(NULL);
 
 	return execv_git_cmd(cvsserver_argv);
 }
-- 
gitgui.0.8.4.11176.gd9205-dirty

^ 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