Git development
 help / color / mirror / Atom feed
* Re: [PATCH] Color support for "git-add -i"
From: Wincent Colaiuta @ 2007-12-05 13:55 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Dan Zwell, Jeff King, git
In-Reply-To: <7vbq95tnk7.fsf@gitster.siamese.dyndns.org>

El 5/12/2007, a las 11:59, Junio C Hamano escribió:

> This is mostly lifted from earlier series by Dan Zwell, but updated to
> use "git config --get-color" to make it simpler and more consistent  
> with
> commands written in C.

Tested here and seems to work well. This is a nice little bit of  
usability polish.

Cheers,
Wincent

^ permalink raw reply

* [PATCH] git config: Don't rely on regexec() returning 1 on non-match
From: Björn Steinbrink @ 2007-12-05 15:11 UTC (permalink / raw)
  To: gitster; +Cc: git, Björn Steinbrink, Johannes Schindelin

Some systems don't return 1 from regexec() when the pattern does not
match (notably HP-UX which returns 20). Fortunately, there's the
REG_NOMATCH constant, which we can use as the expected return value
and test for that instead of "1 XOR retval".

Bug identified by Dscho and H.Merijn Brand.

Signed-off-by: Björn Steinbrink <B.Steinbrink@gmx.de>
Tested-by: H.Merijn Brand <h.m.brand@xs4all.nl>
Cc: Johannes Schindelin <Johannes.Schindelin@gmx.de>
---
 builtin-config.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/builtin-config.c b/builtin-config.c
index 4c9ded3..9fda4e4 100644
--- a/builtin-config.c
+++ b/builtin-config.c
@@ -11,7 +11,7 @@ static regex_t *regexp;
 static int show_keys;
 static int use_key_regexp;
 static int do_all;
-static int do_not_match;
+static int expected_regexec_result;
 static int seen;
 static char delim = '=';
 static char key_delim = ' ';
@@ -38,7 +38,7 @@ static int show_config(const char* key_, const char* value_)
 	if (use_key_regexp && regexec(key_regexp, key_, 0, NULL, 0))
 		return 0;
 	if (regexp != NULL &&
-			 (do_not_match ^
+			 (expected_regexec_result !=
 			  regexec(regexp, (value_?value_:""), 0, NULL, 0)))
 		return 0;
 
@@ -101,7 +101,7 @@ static int get_value(const char* key_, const char* regex_)
 
 	if (regex_) {
 		if (regex_[0] == '!') {
-			do_not_match = 1;
+			expected_regexec_result = REG_NOMATCH;
 			regex_++;
 		}
 
-- 
1.5.3.GIT

^ permalink raw reply related

* Re: [PATCH] git config: Don't rely on regexec() returning 1 on non-match
From: Johannes Schindelin @ 2007-12-05 15:14 UTC (permalink / raw)
  To: Björn Steinbrink; +Cc: gitster, git
In-Reply-To: <1196867484-22188-1-git-send-email-B.Steinbrink@gmx.de>

[-- Attachment #1: Type: TEXT/PLAIN, Size: 538 bytes --]

Hi,

On Wed, 5 Dec 2007, Björn Steinbrink wrote:

> Some systems don't return 1 from regexec() when the pattern does not
> match (notably HP-UX which returns 20). Fortunately, there's the
> REG_NOMATCH constant, which we can use as the expected return value
> and test for that instead of "1 XOR retval".
> 
> Bug identified by Dscho and H.Merijn Brand.
> 
> Signed-off-by: Björn Steinbrink <B.Steinbrink@gmx.de>
> Tested-by: H.Merijn Brand <h.m.brand@xs4all.nl>
> Cc: Johannes Schindelin <Johannes.Schindelin@gmx.de>

ACK

Ciao,
Dscho

^ permalink raw reply

* Re: * [BUG] "git clean" does not pay attention to its parameters
From: Shawn Bohrer @ 2007-12-05 15:28 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Nanako Shiraishi, git
In-Reply-To: <7veje1zibm.fsf@gitster.siamese.dyndns.org>

On Tue, Dec 04, 2007 at 11:55:41PM -0800, Junio C Hamano wrote:
> Does this patch help?  I am not sure why the directory side of the code
> is written that way, but I have a suspicion that "was a directory
> explicitly given as one of the pathspec" check is also bogus, although I
> did not touch that part.

Before the rewrite in C git clean would refuse to remove a directory if
you said:

   git clean dir

without using the -d parameter.  Per your suggestion this check causes
git clean to remove the directory anyway since you explicitly asked it
to.

^ permalink raw reply

* Re: How to jump between two repositories ...
From: g2 @ 2007-12-05 15:28 UTC (permalink / raw)
  To: Andreas Ericsson; +Cc: git
In-Reply-To: <47566526.9010900@op5.se>


How do you safely push to the repository? Even if my receiving  
repository is pristine (the last command I do is a commit), after I  
push into it, some files in the work-tree are effectively out of date  
and git says so by thinking they are modified and staged for commit.  
My original set of example commands illustrates this. What set of  
commands do you use to avoid the problem?


On 5-Dec-07, at 12:45 AM, Andreas Ericsson wrote:
>
> Yes it does. It just supports it badly. If there is a work-tree  
> connected to
> the receiving repository and that work-tree is pristine, it would be  
> safe and
> sane to write the newly pushed changes to the connected working tree.
>
> We do all our integration fixups by pushing to repositories with  
> work-trees,
> simply because it's ridiculously inconvenient to add the  
> infrastructure to
> pull to those repos from each individual developer. In that  
> scenario, pushing
> to a checked out branch is highly useful and perfectly safe.
>
> -- 
> Andreas Ericsson                   andreas.ericsson@op5.se
> OP5 AB                             www.op5.se
> Tel: +46 8-230225                  Fax: +46 8-230231

^ permalink raw reply

* Re: Put part of working tree on another file-system.
From: Rogan Dawes @ 2007-12-05 15:34 UTC (permalink / raw)
  To: Sergei Organov; +Cc: git
In-Reply-To: <87mysp8ddk.fsf@osv.gnss.ru>

Sergei Organov wrote:
> Hello,
> 
> I've a desire to put a sub-tree of my working tree into another
> file-system. With CVS I've used symlink to achieve this. It works fine
> with CVS as it doesn't care about directories and symlinks at all. I had
> little hope it will work with GIT, but I've performed a test anyway. To
> my surprise it almost worked, so I have a hope that maybe it's not that
> difficult to support this. What do you think? Or maybe there is a
> different way to achieve the goal with GIT?
> 

I needed to do this in Cygwin, and saw the same behaviour. I worked 
around it by using cygwin's "mount" command to "mount" the other 
directory in Cygwin's namespace. With this done, cygwin does not detect 
a symlink (since there is none), and works as expected.

With sufficient permissions, you can probably achieve the same effect 
with bind mounts perhaps (assuming Linux, of course).

Rogan

^ permalink raw reply

* Re: [PATCH] Do check_repository_format() early
From: Nguyen Thai Ngoc Duy @ 2007-12-05 15:39 UTC (permalink / raw)
  To: git, Junio C Hamano, Johannes Schindelin
In-Reply-To: <20071205132514.GA5580@laptop>

On Dec 5, 2007 8:33 PM, Nguyen Thai Ngoc Duy <pclouds@gmail.com> wrote:
> @@ -287,6 +310,8 @@ const char *setup_git_directory_gently(int *nongit_ok)
>                         if (!work_tree_env)
>                                 inside_work_tree = 0;
>                         setenv(GIT_DIR_ENVIRONMENT, ".", 1);
> +                       if (check_repository_format_gently(nongit_ok))
> +                               return NULL;
>                         return NULL;
>                 }
>                 chdir("..");

This part better be as follow (patch may be damaged as I'm editing it in gmail)

 @@ -287,6 +310,8 @@ const char *setup_git_directory_gently(int *nongit_ok)
                         if (!work_tree_env)
                                 inside_work_tree = 0;
                         setenv(GIT_DIR_ENVIRONMENT, ".", 1);
 +                       check_repository_format_gently(nongit_ok);
                         return NULL;
                 }
                 chdir("..");
-- 
Duy

^ permalink raw reply

* [PATCH/RFC] autoconf: Add test for OLD_ICONV
From: Jakub Narebski @ 2007-12-05 15:45 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Ramsay Jones, Arjen Laarhoven, Brian Gernhardt,
	Jakub Narebski
In-Reply-To: <7vd4u5l29v.fsf@gitster.siamese.dyndns.org>

Update configure.ac (and config.mak.in) to keep up with git
development by adding [compile] test whether your library has
an old iconv(), where the second (input buffer pointer) parameter
is declared with type (const char **) (OLD_ICONV).

Signed-off-by: Jakub Narebski <jnareb@gmail.com>
---
This patch needs checking if it correctly sets OLD_ICONV
when needed.  I have checked only that it is not set when
with new iconv() declaration.  Could people using Cygwin
(and other with OLD_ICONV: Darwin) test it?

I should probably used AC_LANG_PROGRAM like for NO_C99_FORMAT instead
of generating whole programlet^W test program by hand (I hope that for
example I haven't missed some header file which needs to be included);
I have followed example for NO_ICONV / NEEDS_LIBICONV and
NO_DEFLATE_BOUND test.  I'm also not sure if I have put this test in
the correct autoconf section, but that is probably matter of taste.

P.S. Is there any convention on where to use YesPlease, and where
UnfortunatelyYes when setting Makefile build configuration variables?

 config.mak.in |    1 +
 configure.ac  |   21 +++++++++++++++++++++
 2 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/config.mak.in b/config.mak.in
index 11d256e..7d5df9b 100644
--- a/config.mak.in
+++ b/config.mak.in
@@ -41,4 +41,5 @@ NO_STRTOUMAX=@NO_STRTOUMAX@
 NO_SETENV=@NO_SETENV@
 NO_MKDTEMP=@NO_MKDTEMP@
 NO_ICONV=@NO_ICONV@
+OLD_ICONV=@OLD_ICONV@
 NO_DEFLATE_BOUND=@NO_DEFLATE_BOUND@
diff --git a/configure.ac b/configure.ac
index 5f8a15b..5d2936e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -212,6 +212,27 @@ test -n "$NEEDS_SOCKET" && LIBS="$LIBS -lsocket"
 
 
 ## Checks for header files.
+AC_MSG_NOTICE([CHECKS for header files])
+#
+# Define OLD_ICONV if your library has an old iconv(), where the second
+# (input buffer pointer) parameter is declared with type (const char **).
+AC_DEFUN([OLDICONVTEST_SRC], [[
+#include <iconv.h>
+
+int main(void)
+{
+	iconv_t cd;
+	char *ibp, *obp;
+	size_t insz, outsz;
+	iconv(cd, &ibp, &insz, &obp, &outsz);
+}
+]])
+AC_MSG_CHECKING([for old iconv()])
+AC_COMPILE_IFELSE(OLDICONVTEST_SRC,
+	[AC_MSG_RESULT([no])],
+	[AC_MSG_RESULT([yes])
+	OLD_ICONV=YesPlease])
+AC_SUBST(OLD_ICONV)
 
 
 ## Checks for typedefs, structures, and compiler characteristics.
-- 
1.5.3.6

^ permalink raw reply related

* Re: [PATCH/RFC] autoconf: Add test for OLD_ICONV
From: Brian Gernhardt @ 2007-12-05 16:11 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git, Junio C Hamano, Ramsay Jones, Arjen Laarhoven
In-Reply-To: <1196869526-2197-1-git-send-email-jnareb@gmail.com>


On Dec 5, 2007, at 10:45 AM, Jakub Narebski wrote:

> Update configure.ac (and config.mak.in) to keep up with git
> development by adding [compile] test whether your library has
> an old iconv(), where the second (input buffer pointer) parameter
> is declared with type (const char **) (OLD_ICONV).
>
> Signed-off-by: Jakub Narebski <jnareb@gmail.com>
> ---
> This patch needs checking if it correctly sets OLD_ICONV
> when needed.  I have checked only that it is not set when
> with new iconv() declaration.  Could people using Cygwin
> (and other with OLD_ICONV: Darwin) test it?

I could not get git am to apply the patch cleanly, but will try again  
later when I have more time.  That said, 10.5's default /usr/include/ 
iconv.h uses the newer non-const definition of iconv_open.  I've had  
to add a "OLD_ICONV=" line to my config.mak to avoid the warning.   
I'll still test to look for a false positive.

> P.S. Is there any convention on where to use YesPlease, and where
> UnfortunatelyYes when setting Makefile build configuration variables?

AFAICT, YesPlease is the "normal" choice and UnfortunatelyYes is used  
when the person who added it considered it an obnoxious hack or a  
stupid failing in a system.  The test in the Makefile is just if the  
variable is defined, so you technically could use  
"IDontLikeSillyVariableValuesInMyMakefiles", and it would work just  
fine.  ;-)

~~ Brian

^ permalink raw reply

* Re: How to jump between two repositories ...
From: Andreas Ericsson @ 2007-12-05 16:19 UTC (permalink / raw)
  To: g2; +Cc: git
In-Reply-To: <9F403ACE-62C0-4A6D-945C-3DA6DF0316B8@gmail.com>

post
top-
don't
Please

g2 wrote:
> 
> How do you safely push to the repository? Even if my receiving 
> repository is pristine (the last command I do is a commit), after I push 
> into it, some files in the work-tree are effectively out of date and git 
> says so by thinking they are modified and staged for commit. My original 
> set of example commands illustrates this. What set of commands do you 
> use to avoid the problem?
> 

Vanilla git-push, ofcourse. I just make sure to run "git reset --hard" in
the receiving repo before using anything in it. Granted, it's "safe"
because I know I never want to use any changes from those repos and not.

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

^ permalink raw reply

* Re: [PATCH/RFC] autoconf: Add test for OLD_ICONV
From: Wincent Colaiuta @ 2007-12-05 16:31 UTC (permalink / raw)
  To: Jakub Narebski
  Cc: git, Junio C Hamano, Ramsay Jones, Arjen Laarhoven,
	Brian Gernhardt
In-Reply-To: <1196869526-2197-1-git-send-email-jnareb@gmail.com>

El 5/12/2007, a las 16:45, Jakub Narebski escribió:

> Update configure.ac (and config.mak.in) to keep up with git
> development by adding [compile] test whether your library has
> an old iconv(), where the second (input buffer pointer) parameter
> is declared with type (const char **) (OLD_ICONV).
>
> Signed-off-by: Jakub Narebski <jnareb@gmail.com>
> ---
> This patch needs checking if it correctly sets OLD_ICONV
> when needed.  I have checked only that it is not set when
> with new iconv() declaration.  Could people using Cygwin
> (and other with OLD_ICONV: Darwin) test it?

Before applying your patch:

     CC utf8.o
utf8.c: In function ‘reencode_string’:
utf8.c:328: warning: passing argument 2 of ‘iconv’ from incompatible  
pointer type
     CC convert.o

After applying your patch:

     CC utf8.o
     CC convert.o

This on Darwin Kernel Version 9.1.0 (Mac OS X 10.5.1).

Cheers,
Wincent

^ permalink raw reply

* Re: [PATCH/RFC] autoconf: Add test for OLD_ICONV
From: Jakub Narebski @ 2007-12-05 16:33 UTC (permalink / raw)
  To: Brian Gernhardt; +Cc: git
In-Reply-To: <82D48BF0-E01D-4CE4-92F3-44B555531624@silverinsanity.com>

On Wed, 5 Dec 2007, Brian Gernhardt wrote:
> On Dec 5, 2007, at 10:45 AM, Jakub Narebski wrote:
> 
> > This patch needs checking if it correctly sets OLD_ICONV
> > when needed.  I have checked only that it is not set when
> > with new iconv() declaration.  Could people using Cygwin
> > (and other with OLD_ICONV: Darwin) test it?
> 
> I could not get git am to apply the patch cleanly, but will try again  
> later when I have more time.

Hmmm... it should apply cleanly to both 'master' (7a4a2e1f797)
and 'next' (bd1cfb7fbddc). It just adds some contents...

-- 
Jakub Narebski
Poland

^ permalink raw reply

* Re: [PATCH/RFC] autoconf: Add test for OLD_ICONV
From: Jakub Narebski @ 2007-12-05 16:52 UTC (permalink / raw)
  To: Wincent Colaiuta
  Cc: git, Junio C Hamano, Ramsay Jones, Arjen Laarhoven,
	Brian Gernhardt
In-Reply-To: <ADB12552-AD67-4781-B194-AD15CA4A7B44@wincent.com>

On Wed, 5 December 2007, Wincent Colaiuta wrote:
> El 5/12/2007, a las 16:45, Jakub Narebski escribió:
> 
> > Update configure.ac (and config.mak.in) to keep up with git
> > development by adding [compile] test whether your library has
> > an old iconv(), where the second (input buffer pointer) parameter
> > is declared with type (const char **) (OLD_ICONV).
> >
> > Signed-off-by: Jakub Narebski <jnareb@gmail.com>
> > ---
> > This patch needs checking if it correctly sets OLD_ICONV
> > when needed.  I have checked only that it is not set when
> > with new iconv() declaration.  Could people using Cygwin
> > (and other with OLD_ICONV: Darwin) test it?
> 
> Before applying your patch:
> 
>      CC utf8.o
> utf8.c: In function ‘reencode_string’:
> utf8.c:328: warning: passing argument 2 of ‘iconv’ from incompatible  
> pointer type
>      CC convert.o
> 
> After applying your patch:
> 
>      CC utf8.o
>      CC convert.o

Do I understand correctly that above is excerpt from the output of the 
following sequence of commands before and after this patch applied?

  $ make configure
  $ ./configure [options]
  $ make

Do you have something like below in ./configure output?

  configure: CHECKS for header files
  checking for old iconv()... yes

> This on Darwin Kernel Version 9.1.0 (Mac OS X 10.5.1).

Strange... in Makefile there is

  ifeq ($(uname_S),Darwin)
	NEEDS_SSL_WITH_CRYPTO = YesPlease
	NEEDS_LIBICONV = YesPlease
	OLD_ICONV = UnfortunatelyYes
	NO_STRLCPY = YesPlease
	NO_MEMMEM = YesPlease
  endif

so the uname based guessing should set OLD_ICONV on Darwin...
-- 
Jakub Narebski
Poland

^ permalink raw reply

* builtin command's prefix question
From: Nguyen Thai Ngoc Duy @ 2007-12-05 16:56 UTC (permalink / raw)
  To: Git Mailing List

Hi,

I have been looking at setup_git_directory_gently() lately. From my
understanding, setup_git_directory* will return a string called
"prefix" that is passed to builtin commands. What is the exact meaning
of this prefix? Correct me if I'm wrong. In early (read: no worktree)
days, cwd was moved to working root directory and prefix contained
relative path from working root directory to the original cwd. So it
had a few implications:
 1. A non-empty prefix indicates cwd has been moved
 2. If cwd is moved, it is moved to working root directory
 3. cwd+prefix should point to the current directory at the time the
command was issued (let's call it "user cwd")

Things change a bit since the rise of worktree:
 - If GIT_DIR is set and GIT_WORK_TREE is not, prefix is relative to
the to-be-set-up worktree, but cwd is not changed, so point 3 is gone.
 - If GIT_DIR is not set and GiT_WORK_TREE is,
  - and it is found that user cwd is inside a gitdir (bare repo), cwd
has been moved and prefix is empty, cwd+prefix no longer point to user
cwd
  - for other cases, cwd may not be worktree (the real worktree will
be setup in setup_work_tree or setup_git_directory)

Now that setup_work_tree can move cwd, it should also change prefix to
meet point 3. But it does not.

I feel dizzy now. Were my assumptions wrong? What is expected behavior
of setup_git_directory_gently()?
-- 
Duy

^ permalink raw reply

* Re: Put part of working tree on another file-system.
From: Sergei Organov @ 2007-12-05 17:07 UTC (permalink / raw)
  To: Rogan Dawes; +Cc: git
In-Reply-To: <4756C51C.8080608@dawes.za.net>

Rogan Dawes <lists@dawes.za.net> writes:

> Sergei Organov wrote:
>> Hello,
>>
>> I've a desire to put a sub-tree of my working tree into another
>> file-system. With CVS I've used symlink to achieve this. It works fine
>> with CVS as it doesn't care about directories and symlinks at all. I had
>> little hope it will work with GIT, but I've performed a test anyway. To
>> my surprise it almost worked, so I have a hope that maybe it's not that
>> difficult to support this. What do you think? Or maybe there is a
>> different way to achieve the goal with GIT?
>>
>
> I needed to do this in Cygwin, and saw the same behaviour. I worked
> around it by using cygwin's "mount" command to "mount" the other
> directory in Cygwin's namespace. With this done, cygwin does not
> detect a symlink (since there is none), and works as expected.
>
> With sufficient permissions, you can probably achieve the same effect
> with bind mounts perhaps (assuming Linux, of course).

Thanks for the idea, -- it seems to work.

[In fact it is Linux, and those "another file-system" is FAT32 partition,
so that, when rebooting to Windoze, this directory could be accessed from
there. I can't put all the working tree there as there are parts of the
tree that depend on file system being case-sensitive.]

-- 
Sergei.

^ permalink raw reply

* [PATCH] Compile fix for SCO OpenServer
From: Aidan Van Dyk @ 2007-12-05 17:21 UTC (permalink / raw)
  To: git

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

SCO OpenServer hides the definitions of (at least) u_short and friends if
_XOPEN_SOURCE is defined.

Signed-off-by: Aidan Van Dyk <aidan@highrise.ca>
---

diff --git a/git-compat-util.h b/git-compat-util.h
index ca0a597..be8cbe8 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -24,7 +24,7 @@
 /* Approximation of the length of the decimal representation of this type. */
 #define decimal_length(x)      ((int)(sizeof(x) * 2.56 + 0.5) + 1)

-#if !defined(__APPLE__) && !defined(__FreeBSD__)
+#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined (__OPENSERVER__)
 #define _XOPEN_SOURCE 600 /* glibc2 and AIX 5.3L need 500, OpenBSD needs 600 for S_ISLNK() */
 #define _XOPEN_SOURCE_EXTENDED 1 /* AIX 5.3L needs this */
 #endif

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply related

* Re: * [BUG] "git clean" does not pay attention to its parameters
From: Jeff King @ 2007-12-05 18:03 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Nanako Shiraishi, Shawn Bohrer, git
In-Reply-To: <7veje1zibm.fsf@gitster.siamese.dyndns.org>

On Tue, Dec 04, 2007 at 11:55:41PM -0800, Junio C Hamano wrote:

> Yuck.  People actually use git-clean?

I use it all the time (though never with arguments, or I probably would
have noticed this bug). I think it is coupled with the "use git status
to see what is going on" workflow that, IIRC, you don't use.

Also, nit: don't you mean "git clean"? :)

-Peff

^ permalink raw reply

* [PATCH 0/6] builtin-remote
From: Johannes Schindelin @ 2007-12-05 19:00 UTC (permalink / raw)
  To: git, gitster

Hi,

this series introduces remote as a builtin, and fixes a long-standing bug 
(if you created a remote with --mirror, prune would not do the right 
thing).

I know it is pretty late in the game for 1.5.4, but then, I do not expect 
this to go into that version...

Ciao,
Dscho

^ permalink raw reply

* (unknown)
From: Johannes Schindelin @ 2007-12-05 19:00 UTC (permalink / raw)
  To: git, gitster
In-Reply-To: <Pine.LNX.4.64.0712051858270.27959@racer.site>

[PATCH 1/6] path-list: add functions to work with unsorted lists

Up to now, path-lists were sorted at all times.  But sometimes it
is much more convenient to build the list and sort it at the end,
or sort it not at all.

Add path_list_append() and sort_path_list() to allow that.

Also, add the unsorted_path_list_has_path() function, to do a linear
search.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---

	I should have done this much earlier...

 path-list.c |   30 ++++++++++++++++++++++++++++++
 path-list.h |    8 +++++++-
 2 files changed, 37 insertions(+), 1 deletions(-)

diff --git a/path-list.c b/path-list.c
index 3d83b7b..92e5cf2 100644
--- a/path-list.c
+++ b/path-list.c
@@ -102,3 +102,33 @@ void print_path_list(const char *text, const struct path_list *p)
 	for (i = 0; i < p->nr; i++)
 		printf("%s:%p\n", p->items[i].path, p->items[i].util);
 }
+
+struct path_list_item *path_list_append(const char *path, struct path_list *list)
+{
+	ALLOC_GROW(list->items, list->nr + 1, list->alloc);
+	list->items[list->nr].path =
+		list->strdup_paths ? xstrdup(path) : (char *)path;
+	return list->items + list->nr++;
+}
+
+static int cmp_items(const void *a, const void *b)
+{
+	const struct path_list_item *one = a;
+	const struct path_list_item *two = b;
+	return strcmp(one->path, two->path);
+}
+
+void sort_path_list(struct path_list *list)
+{
+	qsort(list->items, list->nr, sizeof(*list->items), cmp_items);
+}
+
+int unsorted_path_list_has_path(struct path_list *list, const char *path)
+{
+	int i;
+	for (i = 0; i < list->nr; i++)
+		if (!strcmp(path, list->items[i].path))
+			return 1;
+	return 0;
+}
+
diff --git a/path-list.h b/path-list.h
index 5931e2c..ca2cbba 100644
--- a/path-list.h
+++ b/path-list.h
@@ -13,10 +13,16 @@ struct path_list
 };
 
 void print_path_list(const char *text, const struct path_list *p);
+void path_list_clear(struct path_list *list, int free_util);
 
+/* Use these functions only on sorted lists: */
 int path_list_has_path(const struct path_list *list, const char *path);
-void path_list_clear(struct path_list *list, int free_util);
 struct path_list_item *path_list_insert(const char *path, struct path_list *list);
 struct path_list_item *path_list_lookup(const char *path, struct path_list *list);
 
+/* Use these functions only on unsorted lists: */
+struct path_list_item *path_list_append(const char *path, struct path_list *list);
+void sort_path_list(struct path_list *list);
+int unsorted_path_list_has_path(struct path_list *list, const char *path);
+
 #endif /* PATH_LIST_H */
-- 
1.5.3.7.2157.g9598e

^ permalink raw reply related

* [PATCH 2/6] parseopt: add flag to stop on first non option
From: Johannes Schindelin @ 2007-12-05 19:01 UTC (permalink / raw)
  To: git, gitster
In-Reply-To: <Pine.LNX.4.64.0712051858270.27959@racer.site>


Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---

	This allows "git remote --option command --command-option".

 parse-options.c |    2 ++
 parse-options.h |    1 +
 2 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/parse-options.c b/parse-options.c
index e12b428..6df1230 100644
--- a/parse-options.c
+++ b/parse-options.c
@@ -229,6 +229,8 @@ int parse_options(int argc, const char **argv, const struct option *options,
 		const char *arg = args.argv[0];
 
 		if (*arg != '-' || !arg[1]) {
+			if (flags & PARSE_OPT_STOP_AT_NON_OPTION)
+				break;
 			argv[j++] = args.argv[0];
 			continue;
 		}
diff --git a/parse-options.h b/parse-options.h
index 102ac31..0d40cd2 100644
--- a/parse-options.h
+++ b/parse-options.h
@@ -18,6 +18,7 @@ enum parse_opt_type {
 
 enum parse_opt_flags {
 	PARSE_OPT_KEEP_DASHDASH = 1,
+	PARSE_OPT_STOP_AT_NON_OPTION = 2,
 };
 
 enum parse_opt_option_flags {
-- 
1.5.3.7.2157.g9598e

^ permalink raw reply related

* Re: your mail
From: Johannes Schindelin @ 2007-12-05 19:01 UTC (permalink / raw)
  To: git, gitster
In-Reply-To: <Pine.LNX.4.64.0712051900370.27959@racer.site>

Hi,

On Wed, 5 Dec 2007, Johannes Schindelin wrote:

> [PATCH 1/6] path-list: add functions to work with unsorted lists

Ooops.

Sorry,
Dscho

^ permalink raw reply

* [PATCH 3/6] Test "git remote show" and "git remote prune"
From: Johannes Schindelin @ 2007-12-05 19:02 UTC (permalink / raw)
  To: git, gitster
In-Reply-To: <Pine.LNX.4.64.0712051858270.27959@racer.site>


While at it, also fix a few instances where a cd was done outside of a
subshell.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 t/t5505-remote.sh |   34 ++++++++++++++++++++++++++++++++++
 1 files changed, 34 insertions(+), 0 deletions(-)

diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh
index 636aec2..c7d7242 100755
--- a/t/t5505-remote.sh
+++ b/t/t5505-remote.sh
@@ -97,4 +97,38 @@ test_expect_success 'remove remote' '
 )
 '
 
+cat > test/expect << EOF
+* remote origin
+  URL: $(pwd)/one/.git
+  Remote branch(es) merged with 'git pull' while on branch master
+    master
+  New remote branches (next fetch will store in remotes/origin)
+    master
+  Tracked remote branches
+    side master
+EOF
+
+test_expect_success 'show' '
+	(cd test &&
+	 git config --add remote.origin.fetch \
+		refs/heads/master:refs/heads/upstream &&
+	 git fetch &&
+	 git branch -d -r origin/master &&
+	 (cd ../one &&
+	  echo 1 > file &&
+	  git commit -m update file) &&
+	 git remote show origin > output &&
+	 git diff expect output)
+'
+
+test_expect_success 'prune' '
+	(cd one &&
+	 git branch -m side side2) &&
+	(cd test &&
+	 git fetch origin &&
+	 git remote prune origin &&
+	 git rev-parse refs/remotes/origin/side2 &&
+	 ! git rev-parse refs/remotes/origin/side)
+'
+
 test_done
-- 
1.5.3.7.2157.g9598e

^ permalink raw reply related

* [PATCH 4/6] Make git-remote a builtin
From: Johannes Schindelin @ 2007-12-05 19:02 UTC (permalink / raw)
  To: git, gitster
In-Reply-To: <Pine.LNX.4.64.0712051858270.27959@racer.site>


Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 Makefile                                           |    3 +-
 builtin-remote.c                                   |  517 ++++++++++++++++++++
 builtin.h                                          |    1 +
 .../examples/git-remote.perl                       |    0 
 git.c                                              |    1 +
 remote.c                                           |    3 +-
 remote.h                                           |    1 +
 t/t5505-remote.sh                                  |    4 +-
 8 files changed, 526 insertions(+), 4 deletions(-)
 create mode 100644 builtin-remote.c
 rename git-remote.perl => contrib/examples/git-remote.perl (100%)

diff --git a/Makefile b/Makefile
index 233bb5f..e840ca3 100644
--- a/Makefile
+++ b/Makefile
@@ -228,7 +228,7 @@ SCRIPT_SH = \
 SCRIPT_PERL = \
 	git-add--interactive.perl \
 	git-archimport.perl git-cvsimport.perl git-relink.perl \
-	git-cvsserver.perl git-remote.perl git-cvsexportcommit.perl \
+	git-cvsserver.perl git-cvsexportcommit.perl \
 	git-send-email.perl git-svn.perl
 
 SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH)) \
@@ -362,6 +362,7 @@ BUILTIN_OBJS = \
 	builtin-push.o \
 	builtin-read-tree.o \
 	builtin-reflog.o \
+	builtin-remote.o \
 	builtin-send-pack.o \
 	builtin-config.o \
 	builtin-rerere.o \
diff --git a/builtin-remote.c b/builtin-remote.c
new file mode 100644
index 0000000..41ac4a1
--- /dev/null
+++ b/builtin-remote.c
@@ -0,0 +1,517 @@
+#include "cache.h"
+#include "parse-options.h"
+#include "transport.h"
+#include "remote.h"
+#include "path-list.h"
+#include "strbuf.h"
+#include "run-command.h"
+#include "refs.h"
+
+static const char * const builtin_remote_usage[] = {
+	"git remote",
+        "git remote add <name> <url>",
+        "git remote rm <name>",
+        "git remote show <name>",
+        "git remote prune <name>",
+        "git remote update [group]",
+	NULL
+};
+
+static int verbose;
+
+static inline int postfixcmp(const char *string, const char *postfix)
+{
+	int len1 = strlen(string), len2 = strlen(postfix);
+	if (len1 < len2)
+		return 1;
+	return strcmp(string + len1 - len2, postfix);
+}
+
+static inline const char *skip_prefix(const char *name, const char *prefix)
+{
+	return !name ? "" :
+		prefixcmp(name, prefix) ?  name : name + strlen(prefix);
+}
+
+static int opt_parse_track(const struct option *opt, const char *arg, int not)
+{
+	struct path_list *list = opt->value;
+	if (not)
+		path_list_clear(list, 0);
+	else
+		path_list_append(arg, list);
+	return 0;
+}
+
+static int fetch_remote(const char *name)
+{
+	const char *argv[] = { "fetch", name, NULL };
+	if (run_command_v_opt(argv, RUN_GIT_CMD))
+		return error ("Could not fetch %s", name);
+	return 0;
+}
+
+static int add(int argc, const char **argv)
+{
+	int fetch = 0, mirror = 0;
+	struct path_list track = { NULL, 0, 0 };
+	const char *master = NULL;
+	struct remote *remote;
+	struct strbuf buf, buf2;
+	const char *name, *url;
+	int i;
+
+	struct option options[] = {
+		OPT_GROUP("add specific options"),
+		OPT_BOOLEAN('f', "fetch", &fetch, "fetch the remote branches"),
+		OPT_CALLBACK('t', "track", &track, "branch",
+			"branch(es) to track", opt_parse_track),
+		OPT_STRING('m', "master", &master, "branch", "master branch"),
+		OPT_BOOLEAN(0, "mirror", &mirror, "no separate remotes"),
+		OPT_END()
+	};
+
+	argc = parse_options(argc, argv, options, builtin_remote_usage, 0);
+
+	if (argc < 2)
+		usage_with_options(builtin_remote_usage, options);
+
+	name = argv[0];
+	url = argv[1];
+
+	remote = remote_get(name);
+	if (remote && (remote->url_nr > 1 || strcmp(name, remote->url[0]) ||
+			remote->fetch_refspec_nr))
+		die ("remote %s already exists.", name);
+
+	strbuf_init(&buf, 0);
+	strbuf_init(&buf2, 0);
+
+	strbuf_addf(&buf, "remote.%s.url", name);
+	if (git_config_set(buf.buf, url))
+		return 1;
+
+	if (track.nr == 0)
+		path_list_append("*", &track);
+	for (i = 0; i < track.nr; i++) {
+		struct path_list_item *item = track.items + i;
+
+		strbuf_reset(&buf);
+		strbuf_addf(&buf, "remote.%s.fetch", name);
+
+		strbuf_reset(&buf2);
+		if (mirror)
+			strbuf_addf(&buf2, "refs/%s:refs/%s",
+					item->path, item->path);
+		else
+			strbuf_addf(&buf2, "refs/heads/%s:refs/remotes/%s/%s",
+					item->path, name, item->path);
+		if (git_config_set_multivar(buf.buf, buf2.buf, "^$", 0))
+			return 1;
+	}
+
+	if (fetch && fetch_remote(name))
+		return 1;
+
+	if (master) {
+		strbuf_reset(&buf);
+		strbuf_addf(&buf, "refs/remotes/%s/HEAD", name);
+
+		strbuf_reset(&buf2);
+		strbuf_addf(&buf2, "refs/remotes/%s/%s", name, master);
+
+		if (create_symref(buf.buf, buf2.buf, "remote add"))
+			return error ("Could not setup master '%s'", master);
+	}
+
+	strbuf_release(&buf);
+	strbuf_release(&buf2);
+	path_list_clear(&track, 0);
+
+	return 0;
+}
+
+struct branch_info {
+	char *remote;
+	struct path_list merge;
+};
+
+static struct path_list branch_list;
+
+static int config_read_branches(const char *key, const char *value)
+{
+	if (!prefixcmp(key, "branch.")) {
+		char *name;
+		struct path_list_item *item;
+		struct branch_info *info;
+		enum { REMOTE, MERGE } type;
+
+		key += 7;
+		if (!postfixcmp(key, ".remote")) {
+			name = xstrndup(key, strlen(key) - 7);
+			type = REMOTE;
+		} else if (!postfixcmp(key, ".merge")) {
+			name = xstrndup(key, strlen(key) - 6);
+			type = MERGE;
+		} else
+			return 0;
+
+		item = path_list_insert(name, &branch_list);
+
+		if (!item->util)
+			item->util = xcalloc(sizeof(struct branch_info), 1);
+		info = item->util;
+		if (type == REMOTE) {
+			if (info->remote)
+				warning ("more than one branch.%s", key);
+			info->remote = xstrdup(value);
+		} else {
+			char *space = strchr(value, ' ');
+			value = skip_prefix(value, "refs/heads/");
+			while (space) {
+				char *merge;
+				merge = xstrndup(value, space - value);
+				path_list_append(merge, &info->merge);
+				value = skip_prefix(space + 1, "refs/heads/");
+				space = strchr(value, ' ');
+			}
+			path_list_append(xstrdup(value), &info->merge);
+		}
+	}
+	return 0;
+}
+
+static void read_branches()
+{
+	if (branch_list.nr)
+		return;
+	git_config(config_read_branches);
+	sort_path_list(&branch_list);
+}
+
+struct ref_states {
+	struct remote *remote;
+	struct strbuf remote_prefix;
+	struct path_list new, stale, tracked;
+};
+
+static int handle_one_branch(const char *refname,
+	const unsigned char *sha1, int flags, void *cb_data)
+{
+	struct ref_states *states = cb_data;
+	struct refspec refspec;
+
+	memset(&refspec, 0, sizeof(refspec));
+	refspec.dst = (char *)refname;
+	if (!remote_find_tracking(states->remote, &refspec)) {
+		struct path_list_item *item;
+		const char *name = skip_prefix(refspec.src, "refs/heads/");
+		if (unsorted_path_list_has_path(&states->tracked, name) ||
+				unsorted_path_list_has_path(&states->new,
+					name))
+			return 0;
+		item = path_list_append(name, &states->stale);
+		item->util = xstrdup(refname);
+	}
+	return 0;
+}
+
+static int get_ref_states(const struct ref *ref, struct ref_states *states)
+{
+	struct ref *fetch_map = NULL, **tail = &fetch_map;
+	int i;
+
+	for (i = 0; i < states->remote->fetch_refspec_nr; i++)
+		if (get_fetch_map(ref, states->remote->fetch +i, &tail, 1))
+			die ("Could not get fetch map for refspec %s",
+				states->remote->fetch_refspec[i]);
+
+	states->new.strdup_paths = states->tracked.strdup_paths = 1;
+	for (ref = fetch_map; ref; ref = ref->next) {
+		struct path_list *target = &states->tracked;
+		unsigned char sha1[20];
+		void *util = NULL;
+
+		if (!ref->peer_ref || read_ref(ref->peer_ref->name, sha1))
+			target = &states->new;
+		else {
+			target = &states->tracked;
+			if (hashcmp(sha1, ref->new_sha1))
+				util = &states;
+		}
+		path_list_append(skip_prefix(ref->name, "refs/heads/"),
+				target)->util = util;
+	}
+	free_refs(fetch_map);
+
+	strbuf_addf(&states->remote_prefix,
+		"refs/remotes/%s/", states->remote->name);
+	for_each_ref(handle_one_branch, states);
+	sort_path_list(&states->stale);
+
+	return 0;
+}
+
+static int remove_tracking_branch(const char *refname,
+	const unsigned char *sha1, int flags, void *cb_data)
+{
+	const char *remote_prefix = cb_data;
+
+	if (!prefixcmp(refname, remote_prefix) &&
+			delete_ref(refname, sha1))
+		return error("Could not remove branch %s", refname);
+	return 0;
+}
+
+static int rm(int argc, const char **argv)
+{
+	struct option options[] = {
+		OPT_END()
+	};
+	struct remote *remote;
+	struct strbuf buf;
+	int i;
+
+	if (argc != 2)
+		usage_with_options(builtin_remote_usage, options);
+
+	remote = remote_get(argv[1]);
+	if (!remote)
+		die ("No such remote: %s", argv[1]);
+
+	strbuf_init(&buf, 0);
+	strbuf_addf(&buf, "remote.%s", remote->name);
+	if (git_config_rename_section(buf.buf, NULL) < 1)
+		return error("Could not remove config section '%s'", buf.buf);
+
+	read_branches();
+	for (i = 0; i < branch_list.nr; i++) {
+		struct path_list_item *item = branch_list.items +i;
+		struct branch_info *info = item->util;
+		if (info->remote && !strcmp(info->remote, remote->name)) {
+			const char *keys[] = { "remote", "merge", NULL }, **k;
+			for (k = keys; *k; k++) {
+				strbuf_reset(&buf);
+				strbuf_addf(&buf, "branch.%s.%s",
+						item->path, *k);
+				if (git_config_set(buf.buf, NULL)) {
+					strbuf_release(&buf);
+					return -1;
+				}
+			}
+		}
+	}
+
+	/*
+	 * NEEDSTHOUGHT: this could check something like
+	 * !remote_find_tracking(remote, &refspec) to know if the
+	 * branch was really tracked.  But then we'll have to make
+	 * sure that no other remote writes into that branch.
+	 * Probably not worth it.
+	 */
+	strbuf_reset(&buf);
+	strbuf_addf(&buf, "refs/remotes/%s/", remote->name);
+	i = for_each_ref(remove_tracking_branch, buf.buf);
+	strbuf_release(&buf);
+
+	return i;
+}
+
+static void show_list(const char *title, struct path_list *list)
+{
+	int i;
+
+	if (!list->nr)
+		return;
+
+	printf(title, list->nr > 1 ? "es" : "");
+	printf("\n    ");
+	for (i = 0; i < list->nr; i++)
+		printf("%s%s", i ? " " : "", list->items[i].path);
+	printf("\n");
+}
+
+static int show_or_prune(int argc, const char **argv, int prune)
+{
+	int dry_run = 0, result = 0;
+	struct option options[] = {
+		OPT_GROUP("show specific options"),
+		OPT__DRY_RUN(&dry_run),
+		OPT_END()
+	};
+	struct ref_states states;
+
+	argc = parse_options(argc, argv, options, builtin_remote_usage, 0);
+
+	if (argc < 1)
+		usage_with_options(builtin_remote_usage, options);
+
+	memset(&states, 0, sizeof(states));
+	for (; argc; argc--, argv++) {
+		struct transport *transport;
+		const struct ref *ref;
+		struct strbuf buf;
+		int i, got_states;
+
+		states.remote = remote_get(*argv);
+		if (!states.remote)
+			return error("No such remote: %s", *argv);
+		transport = transport_get(NULL, states.remote->url[0]);
+		ref = transport_get_remote_refs(transport);
+
+		read_branches();
+		got_states = get_ref_states(ref, &states);
+		if (got_states)
+			result = error("Error getting local info for '%s'",
+					states.remote->name);
+
+		if (prune) {
+			struct strbuf buf;
+
+			strbuf_init(&buf, 0);
+			for (i = 0; i < states.stale.nr; i++) {
+				strbuf_reset(&buf);
+				strbuf_addf(&buf, "refs/remotes/%s/%s", *argv,
+						states.stale.items[i].path);
+				result |= delete_ref(buf.buf, NULL);
+			}
+
+			strbuf_release(&buf);
+			goto cleanup_states;
+		}
+
+		printf("* remote %s\n  URL: %s\n", *argv,
+			states.remote->url[0] ?
+				states.remote->url[0] : "(no URL)");
+
+		for (i = 0; i < branch_list.nr; i++) {
+			struct path_list_item *branch = branch_list.items + i;
+			struct branch_info *info = branch->util;
+			int j;
+
+			if (!info->merge.nr || strcmp(*argv, info->remote))
+				continue;
+			printf("  Remote branch%s merged with 'git pull' "
+				"while on branch %s\n   ",
+				info->merge.nr > 1 ? "es" : "",
+				branch->path);
+			for (j = 0; j < info->merge.nr; j++)
+				printf(" %s", info->merge.items[j].path);
+			printf("\n");
+		}
+
+		if (got_states)
+			continue;
+		strbuf_init(&buf, 0);
+		strbuf_addf(&buf, "  New remote branch%%s (next fetch will "
+			"store in remotes/%s)", states.remote->name);
+		show_list(buf.buf, &states.new);
+		strbuf_release(&buf);
+		show_list("  Stale tracking branch%s (use 'git remote prune')",
+				&states.stale);
+		show_list("  Tracked remote branch%s",
+				&states.tracked);
+
+		if (states.remote->push_refspec_nr) {
+			printf("  Local branch%s pushed with 'git push'\n   ",
+				states.remote->push_refspec_nr > 1 ?
+					"es" : "");
+			for (i = 0; i < states.remote->push_refspec_nr; i++) {
+				struct refspec *spec = states.remote->push + i;
+				printf(" %s%s%s%s", spec->force ? "+" : "",
+					skip_prefix(spec->src, "refs/heads/"),
+					spec->dst ? ":" : "",
+					skip_prefix(spec->dst, "refs/heads/"));
+			}
+		}
+cleanup_states:
+		/* NEEDSWORK: free remote */
+		path_list_clear(&states.new, 0);
+		path_list_clear(&states.stale, 0);
+		path_list_clear(&states.tracked, 0);
+	}
+
+	return result;
+}
+
+static int update_one(struct remote *remote, void *priv)
+{
+	if (!remote->skip_default_update)
+		return fetch_remote(remote->name);
+	return 0;
+}
+
+static int update(int argc, const char **argv)
+{
+	int i;
+
+	if (argc < 2)
+		return for_each_remote(update_one, NULL);
+
+	for (i = 1; i < argc; i++)
+		if (fetch_remote(argv[i]))
+			return 1;
+	return 0;
+}
+
+static int get_one_entry(struct remote *remote, void *priv)
+{
+	struct path_list *list = priv;
+
+	path_list_append(remote->name, list)->util = (void *)remote->url[0];
+	if (remote->url[0] && remote->url[1])
+		warning ("Remote %s has more than one URL", remote->name);
+
+	return 0;
+}
+
+static int show_all()
+{
+	struct path_list list = { NULL, 0, 0 };
+	int result = for_each_remote(get_one_entry, &list);
+
+	if (!result) {
+		int i;
+
+		sort_path_list(&list);
+		for (i = 0; i < list.nr; i++) {
+			struct path_list_item *item = list.items + i;
+			printf("%s%s%s\n", item->path,
+				verbose ? "\t" : "",
+				verbose && item->util ?
+					(const char *)item->util : "");
+		}
+	}
+	return result;
+}
+
+int cmd_remote(int argc, const char **argv, const char *prefix)
+{
+	struct option options[] = {
+		OPT__VERBOSE(&verbose),
+		OPT_END()
+	};
+	int result;
+
+	argc = parse_options(argc, argv, options, builtin_remote_usage,
+		PARSE_OPT_STOP_AT_NON_OPTION);
+
+	if (argc < 1)
+		result = show_all();
+	else if (!strcmp(argv[0], "add"))
+		result = add(argc, argv);
+	else if (!strcmp(argv[0], "rm"))
+		result = rm(argc, argv);
+	else if (!strcmp(argv[0], "show"))
+		result = show_or_prune(argc, argv, 0);
+	else if (!strcmp(argv[0], "prune"))
+		result = show_or_prune(argc, argv, 1);
+	else if (!strcmp(argv[0], "update"))
+		result = update(argc, argv);
+	else {
+		error ("Unknown subcommand: %s", argv[0]);
+		usage_with_options(builtin_remote_usage, options);
+	}
+
+	return result ? 1 : 0;
+}
diff --git a/builtin.h b/builtin.h
index cb675c4..20b6e75 100644
--- a/builtin.h
+++ b/builtin.h
@@ -66,6 +66,7 @@ extern int cmd_prune_packed(int argc, const char **argv, const char *prefix);
 extern int cmd_push(int argc, const char **argv, const char *prefix);
 extern int cmd_read_tree(int argc, const char **argv, const char *prefix);
 extern int cmd_reflog(int argc, const char **argv, const char *prefix);
+extern int cmd_remote(int argc, const char **argv, const char *prefix);
 extern int cmd_config(int argc, const char **argv, const char *prefix);
 extern int cmd_rerere(int argc, const char **argv, const char *prefix);
 extern int cmd_reset(int argc, const char **argv, const char *prefix);
diff --git a/git-remote.perl b/contrib/examples/git-remote.perl
similarity index 100%
rename from git-remote.perl
rename to contrib/examples/git-remote.perl
diff --git a/git.c b/git.c
index c8b7e74..80e9082 100644
--- a/git.c
+++ b/git.c
@@ -349,6 +349,7 @@ static void handle_internal_command(int argc, const char **argv)
 		{ "push", cmd_push, RUN_SETUP },
 		{ "read-tree", cmd_read_tree, RUN_SETUP },
 		{ "reflog", cmd_reflog, RUN_SETUP },
+		{ "remote", cmd_remote, RUN_SETUP },
 		{ "repo-config", cmd_config },
 		{ "rerere", cmd_rerere, RUN_SETUP },
 		{ "reset", cmd_reset, RUN_SETUP },
diff --git a/remote.c b/remote.c
index 3fb0f99..ae7abe4 100644
--- a/remote.c
+++ b/remote.c
@@ -280,7 +280,8 @@ static int handle_config(const char *key, const char *value)
 			remote->fetch_tags = -1;
 	} else if (!strcmp(subkey, ".proxy")) {
 		remote->http_proxy = xstrdup(value);
-	}
+	} else if (!strcmp(subkey, ".skipdefaultupdate"))
+		remote->skip_default_update = 1;
 	return 0;
 }
 
diff --git a/remote.h b/remote.h
index 86e036d..bb26d3c 100644
--- a/remote.h
+++ b/remote.h
@@ -22,6 +22,7 @@ struct remote {
 	 * 2 to always fetch tags
 	 */
 	int fetch_tags;
+	int skip_default_update;
 
 	const char *receivepack;
 	const char *uploadpack;
diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh
index c7d7242..d343a96 100755
--- a/t/t5505-remote.sh
+++ b/t/t5505-remote.sh
@@ -100,9 +100,9 @@ test_expect_success 'remove remote' '
 cat > test/expect << EOF
 * remote origin
   URL: $(pwd)/one/.git
-  Remote branch(es) merged with 'git pull' while on branch master
+  Remote branch merged with 'git pull' while on branch master
     master
-  New remote branches (next fetch will store in remotes/origin)
+  New remote branch (next fetch will store in remotes/origin)
     master
   Tracked remote branches
     side master
-- 
1.5.3.7.2157.g9598e

^ permalink raw reply related

* [PATCH 5/6] builtin-remote: prune remotes correctly that were added with --mirror
From: Johannes Schindelin @ 2007-12-05 19:02 UTC (permalink / raw)
  To: git, gitster
In-Reply-To: <Pine.LNX.4.64.0712051858270.27959@racer.site>


This adds special handling for mirror remotes.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---

	This fixes a real bug in git-remote, which I tried to fix in the
	perl script, failing.

 builtin-remote.c  |   16 +++++++++++++---
 t/t5505-remote.sh |   16 ++++++++++++++++
 2 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/builtin-remote.c b/builtin-remote.c
index 41ac4a1..142eb97 100644
--- a/builtin-remote.c
+++ b/builtin-remote.c
@@ -367,12 +367,22 @@ static int show_or_prune(int argc, const char **argv, int prune)
 
 		if (prune) {
 			struct strbuf buf;
+			int prefix_len;
 
 			strbuf_init(&buf, 0);
+			if (states.remote->fetch_refspec_nr == 1 &&
+					states.remote->fetch->pattern &&
+					!strcmp(states.remote->fetch->src,
+						states.remote->fetch->dst))
+				/* handle --mirror remote */
+				strbuf_addstr(&buf, "refs/heads/");
+			else
+				strbuf_addf(&buf, "refs/remotes/%s/", *argv);
+			prefix_len = buf.len;
+
 			for (i = 0; i < states.stale.nr; i++) {
-				strbuf_reset(&buf);
-				strbuf_addf(&buf, "refs/remotes/%s/%s", *argv,
-						states.stale.items[i].path);
+				strbuf_setlen(&buf, prefix_len);
+				strbuf_addstr(&buf, states.stale.items[i].path);
 				result |= delete_ref(buf.buf, NULL);
 			}
 
diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh
index d343a96..2376e0a 100755
--- a/t/t5505-remote.sh
+++ b/t/t5505-remote.sh
@@ -131,4 +131,20 @@ test_expect_success 'prune' '
 	 ! git rev-parse refs/remotes/origin/side)
 '
 
+test_expect_success 'add --mirror && prune' '
+	(mkdir mirror &&
+	 cd mirror &&
+	 git init &&
+	 git remote add --mirror -f origin ../one) &&
+	(cd one &&
+	 git branch -m side2 side) &&
+	(cd mirror &&
+	 git rev-parse --verify refs/heads/side2 &&
+	 ! git rev-parse --verify refs/heads/side &&
+	 git fetch origin &&
+	 git remote prune origin &&
+	 ! git rev-parse --verify refs/heads/side2 &&
+	 git rev-parse --verify refs/heads/side)
+'
+
 test_done
-- 
1.5.3.7.2157.g9598e

^ permalink raw reply related

* [PATCH 6/6] DWIM "git add remote ..."
From: Johannes Schindelin @ 2007-12-05 19:03 UTC (permalink / raw)
  To: git, gitster
In-Reply-To: <Pine.LNX.4.64.0712051858270.27959@racer.site>


It is wrong to divert to "git remote add" when you typed the
(more English) "git add remote".  But is it also pretty convenient.

So implement it, but do not document it ;-)

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 builtin-add.c     |    7 +++++++
 t/t5505-remote.sh |    6 ++++++
 2 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/builtin-add.c b/builtin-add.c
index 5c29cc2..b5b4c2f 100644
--- a/builtin-add.c
+++ b/builtin-add.c
@@ -196,6 +196,13 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 	const char **pathspec;
 	struct dir_struct dir;
 
+	if (argc > 1 && !strcmp(argv[1], "remote") &&
+			access("remote", F_OK)) {
+		argv[1] = argv[0];
+		argv[0] = "remote";
+		return cmd_remote(argc, argv, prefix);
+	}
+
 	argc = parse_options(argc, argv, builtin_add_options,
 			  builtin_add_usage, 0);
 	if (patch_interactive)
diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh
index 2376e0a..83ed70c 100755
--- a/t/t5505-remote.sh
+++ b/t/t5505-remote.sh
@@ -147,4 +147,10 @@ test_expect_success 'add --mirror && prune' '
 	 git rev-parse --verify refs/heads/side)
 '
 
+test_expect_success 'add remote' '
+	(cd test &&
+	 git add remote -f another-one ../one &&
+	 git diff master remotes/another-one/master)
+'
+
 test_done
-- 
1.5.3.7.2157.g9598e

^ 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