Git development
 help / color / mirror / Atom feed
* Re: [EGIT PATCH] Change to simplified icon.
From: Johannes Schindelin @ 2007-09-25  9:53 UTC (permalink / raw)
  To: Shawn O. Pearce; +Cc: git
In-Reply-To: <20070925011636.GH3099@spearce.org>

Hi,

On Mon, 24 Sep 2007, Shawn O. Pearce wrote:

> Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> > On Mon, 24 Sep 2007, Shawn O. Pearce wrote:
> > > 
> > > [...] Maybe I'll take a stab at creating
> > > a git-gui icon [...]
> > 
> > You might want to look at http://git.or.cz/gitwiki/GitRelatedLogos (I 
> > especially like Henrik Nyh's, we use it in git-gui).  Might be a good 
> > starting point.
> 
> What do you mean you "use it in git-gui" ?  Have you patched git-gui to 
> set the window icon to Henrik's?  And not tried to contribute the patch 
> upstream?  Come on, show the GPL love... :-)

Oops.  I meant to say that we use it in msysGit.

Sorry,
Dscho

^ permalink raw reply

* Re: [PATCH] Use "" instead of "<unknown>" for placeholders
From: Michal Vitecek @ 2007-09-25  9:43 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Johannes Schindelin
In-Reply-To: <46F4D815.5050602@mageo.cz>

 Hello again,

Michal Vitecek wrote:
> Junio C Hamano wrote:
>>>>>>> I made it because I want to use my own pretty format which currently 
>>>>>>> only allows '%s' for subject and '%b' for body. But '%b' is 
>>>>>>> substituted with <undefined> if the body is "missing" which I 
>>>>>>> obviously don't like :)
>>>>>> Then you should fix %b not to show "<undefined>".
>>>>>  I'll do it if it is okay. Shall I do the same for the other
>>>>>  placeholders as well?
>>>> Yeah.  Don't know why I did it that way.
>>>  Here comes the big patch :)
>> Now, this breaks t6006 which needs this patch.
>
> Oops - I'm sorry about that. I ran the test suite (1.5.3.1) but it failed 
> in 2 tests before the patch and in 2 tests after it so I considered it 
> okay.
>
>> Looking at this patch, I am not sure if your change is really a
>> desirable one --- shouldn't it be removing the line itself, not
>> just <unknown> token?
>
> This sounds as the best solution. I'll look into it. Thanks for your time.

 Here comes the patch. I hope it will be ok this time :) Thanks.

 Don't use "<unknown>" for unknown values of placeholders and suppress
 printing of empty user formats.

---
 builtin-rev-list.c         |    3 ++-
 commit.c                   |    3 ---
 interpolate.c              |    6 +++++-
 log-tree.c                 |   10 ++++++----
 t/t6006-rev-list-format.sh |    8 --------
 t/t7500-commit.sh          |    4 ++--
 6 files changed, 15 insertions(+), 19 deletions(-)

diff --git a/builtin-rev-list.c b/builtin-rev-list.c
index 3894633..1de981d 100644
--- a/builtin-rev-list.c
+++ b/builtin-rev-list.c
@@ -85,7 +85,8 @@ static void show_commit(struct commit *commit)
 		pretty_print_commit(revs.commit_format, commit, ~0,
 				    &buf, &buflen,
 				    revs.abbrev, NULL, NULL, revs.date_mode);
-		printf("%s%c", buf, hdr_termination);
+                if (strlen(buf))
+                    printf("%s%c", buf, hdr_termination);
 		free(buf);
 	}
 	maybe_flush_or_die(stdout, "stdout");
diff --git a/commit.c b/commit.c
index 99f65ce..c9a1818 100644
--- a/commit.c
+++ b/commit.c
@@ -917,9 +917,6 @@ long format_commit_message(const struct commit *commit, const void *format,
 	}
 	if (msg[i])
 		table[IBODY].value = xstrdup(msg + i);
-	for (i = 0; i < ARRAY_SIZE(table); i++)
-		if (!table[i].value)
-			interp_set_entry(table, i, "<unknown>");
 
 	do {
 		char *buf = *buf_p;
diff --git a/interpolate.c b/interpolate.c
index 0082677..58fd055 100644
--- a/interpolate.c
+++ b/interpolate.c
@@ -76,8 +76,12 @@ unsigned long interpolate(char *result, unsigned long reslen,
 			/* Check for valid interpolation. */
 			if (i < ninterps) {
 				value = interps[i].value;
-				valuelen = strlen(value);
+                                if (value == NULL) {
+                                    src += namelen;
+                                    continue;
+                                }
 
+				valuelen = strlen(value);
 				if (newlen + valuelen + 1 < reslen) {
 					/* Substitute. */
 					strncpy(dest, value, valuelen);
diff --git a/log-tree.c b/log-tree.c
index a642371..5653332 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -175,14 +175,15 @@ void show_log(struct rev_info *opt, const char *sep)
 	 *  - The pretty-printed commit lacks a newline at the end
 	 *    of the buffer, but we do want to make sure that we
 	 *    have a newline there. If the separator isn't already
-	 *    a newline, add an extra one.
+         *    a newline, add an extra one and do the same for the
+         *    user format as well.
 	 *  - unlike other log messages, the one-line format does
 	 *    not have an empty line between entries.
 	 */
 	extra = "";
-	if (*sep != '\n' && opt->commit_format == CMIT_FMT_ONELINE)
+	if (*sep != '\n' && (opt->commit_format == CMIT_FMT_ONELINE || opt->commit_format == CMIT_FMT_USERFORMAT))
 		extra = "\n";
-	if (opt->shown_one && opt->commit_format != CMIT_FMT_ONELINE)
+	if (opt->shown_one && opt->commit_format != CMIT_FMT_ONELINE && opt->commit_format != CMIT_FMT_USERFORMAT)
 		putchar(opt->diffopt.line_termination);
 	opt->shown_one = 1;
 
@@ -298,7 +299,8 @@ void show_log(struct rev_info *opt, const char *sep)
 	if (opt->show_log_size)
 		printf("log size %i\n", len);
 
-	printf("%s%s%s", msgbuf, extra, sep);
+        if (strlen(msgbuf))
+            printf("%s%s%s", msgbuf, extra, sep);
 	free(msgbuf);
 }
 
diff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh
index ad6d0b8..1e4541a 100755
--- a/t/t6006-rev-list-format.sh
+++ b/t/t6006-rev-list-format.sh
@@ -79,9 +79,7 @@ EOF
 
 test_format encoding %e <<'EOF'
 commit 131a310eb913d107dd3c09a65d1651175898735d
-<unknown>
 commit 86c75cfd708a0e5868dc876ed5b8bb66c80b4873
-<unknown>
 EOF
 
 test_format subject %s <<'EOF'
@@ -93,9 +91,7 @@ EOF
 
 test_format body %b <<'EOF'
 commit 131a310eb913d107dd3c09a65d1651175898735d
-<unknown>
 commit 86c75cfd708a0e5868dc876ed5b8bb66c80b4873
-<unknown>
 EOF
 
 test_format colors %Credfoo%Cgreenbar%Cbluebaz%Cresetxyzzy <<'EOF'
@@ -121,9 +117,7 @@ test_format complex-encoding %e <<'EOF'
 commit f58db70b055c5718631e5c61528b28b12090cdea
 iso8859-1
 commit 131a310eb913d107dd3c09a65d1651175898735d
-<unknown>
 commit 86c75cfd708a0e5868dc876ed5b8bb66c80b4873
-<unknown>
 EOF
 
 test_format complex-subject %s <<'EOF'
@@ -142,9 +136,7 @@ and it will be encoded in iso8859-1. We should therefore
 include an iso8859 character: ÂĄbueno!
 
 commit 131a310eb913d107dd3c09a65d1651175898735d
-<unknown>
 commit 86c75cfd708a0e5868dc876ed5b8bb66c80b4873
-<unknown>
 EOF
 
 test_done
diff --git a/t/t7500-commit.sh b/t/t7500-commit.sh
index f11ada8..abbf54b 100755
--- a/t/t7500-commit.sh
+++ b/t/t7500-commit.sh
@@ -81,7 +81,7 @@ test_expect_success 'explicit commit message should override template' '
 	git add foo &&
 	GIT_EDITOR=../t7500/add-content git commit --template "$TEMPLATE" \
 		-m "command line msg" &&
-	commit_msg_is "command line msg<unknown>"
+	commit_msg_is "command line msg"
 '
 
 test_expect_success 'commit message from file should override template' '
@@ -90,7 +90,7 @@ test_expect_success 'commit message from file should override template' '
 	echo "standard input msg" |
 		GIT_EDITOR=../t7500/add-content git commit \
 			--template "$TEMPLATE" --file - &&
-	commit_msg_is "standard input msg<unknown>"
+	commit_msg_is "standard input msg"
 '
 
 test_done
-- 
1.5.3.1


-- 
		fuf		(fuf@mageo.cz)

^ permalink raw reply related

* Re: My stash wants to delete all my files
From: Jonathan del Strother @ 2007-09-25  9:27 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Git Mailing List
In-Reply-To: <7vabrb8rin.fsf@gitster.siamese.dyndns.org>


On 25 Sep 2007, at 02:26, Junio C Hamano wrote:

> Jonathan del Strother <maillist@steelskies.com> writes:
>
>> $ git stash list
>> stash@{0}: On master: --apply
>> stash@{1}: WIP on master: 09e3c30... Better handling of cell sizes in
>> the grid
>>
>> $ git stash show stash@{1}
>> ...
>> 19 files changed, 0 insertions(+), 3805 deletions(-)
>>
>> Hmm.  Looks like it's trying to delete all of my versioned files.
>> "git stash apply stash@{1}" confirms this.   Obviously that's not  
>> what
>> I tried to stash - my WIP when I stashed was a few additions, a  
>> couple
>> of new unversioned files, and moving a few lines of code from one  
>> file
>> to another.
>>
>> Any ideas what happened there?  I can't seem to reproduce the problem
>> in a test repository.
>
> ...
> Whenever anybody wonders where inadvertent reverting changes
> come from, two most likely reasons are incorrect push into the
> current branch's tip initiated from elsewhere, or incorrect
> fetch into the current branch's tip initiated from the
> repository.

I'm working on a single isolated repository, so haven't pushed,  
pulled, fetched, or anything.


> 	git ls-tree stash@{1}
>        git rev-parse stash@{1}^1
>        git diff stash@{1}^1 stash@{1}^2
>

ls-tree is empty.  rev-parse confirms I was on the right revision when  
I stashed, and the diff shows everything being deleted.


> Does the third command show you what you thought you have
> told "git add" to put in the index just before you made the
> stash?

I don't think I git-added anything - just made changes to the working  
copy.  (It *does* stash those, right??)


I'm at a loss to explain what happened here...

^ permalink raw reply

* [PATCH] Small cache_tree_write refactor.
From: Pierre Habouzit @ 2007-09-25  8:22 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

This function cannot fail, make it void. Also make write_one act on a
const char* instead of a char*.

Signed-off-by: Pierre Habouzit <madcoder@debian.org>
---
 cache-tree.c |   19 +++++--------------
 cache-tree.h |    2 +-
 read-cache.c |   19 +++++++++----------
 3 files changed, 15 insertions(+), 25 deletions(-)

diff --git a/cache-tree.c b/cache-tree.c
index 5471844..50b3526 100644
--- a/cache-tree.c
+++ b/cache-tree.c
@@ -369,10 +369,8 @@ int cache_tree_update(struct cache_tree *it,
 	return 0;
 }
 
-static void write_one(struct cache_tree *it,
-		       char *path,
-		       int pathlen,
-			   struct strbuf *buffer)
+static void write_one(struct strbuf *buffer, struct cache_tree *it,
+                      const char *path, int pathlen)
 {
 	int i;
 
@@ -407,20 +405,13 @@ static void write_one(struct cache_tree *it,
 					     prev->name, prev->namelen) <= 0)
 				die("fatal - unsorted cache subtree");
 		}
-		write_one(down->cache_tree, down->name, down->namelen, buffer);
+		write_one(buffer, down->cache_tree, down->name, down->namelen);
 	}
 }
 
-void *cache_tree_write(struct cache_tree *root, unsigned long *size_p)
+void cache_tree_write(struct strbuf *sb, struct cache_tree *root)
 {
-	char path[PATH_MAX];
-	struct strbuf buffer;
-
-	path[0] = 0;
-	strbuf_init(&buffer, 0);
-	write_one(root, path, 0, &buffer);
-	*size_p = buffer.len;
-	return strbuf_detach(&buffer);
+	write_one(sb, root, "", 0);
 }
 
 static struct cache_tree *read_one(const char **buffer, unsigned long *size_p)
diff --git a/cache-tree.h b/cache-tree.h
index 119407e..8243228 100644
--- a/cache-tree.h
+++ b/cache-tree.h
@@ -22,7 +22,7 @@ void cache_tree_free(struct cache_tree **);
 void cache_tree_invalidate_path(struct cache_tree *, const char *);
 struct cache_tree_sub *cache_tree_sub(struct cache_tree *, const char *);
 
-void *cache_tree_write(struct cache_tree *root, unsigned long *size_p);
+void cache_tree_write(struct strbuf *, struct cache_tree *root);
 struct cache_tree *cache_tree_read(const char *buffer, unsigned long size);
 
 int cache_tree_fully_valid(struct cache_tree *);
diff --git a/read-cache.c b/read-cache.c
index 2e40a34..56202d1 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -1136,7 +1136,7 @@ int write_index(struct index_state *istate, int newfd)
 {
 	SHA_CTX c;
 	struct cache_header hdr;
-	int i, removed;
+	int i, err, removed;
 	struct cache_entry **cache = istate->cache;
 	int entries = istate->cache_nr;
 
@@ -1165,16 +1165,15 @@ int write_index(struct index_state *istate, int newfd)
 
 	/* Write extension data here */
 	if (istate->cache_tree) {
-		unsigned long sz;
-		void *data = cache_tree_write(istate->cache_tree, &sz);
-		if (data &&
-		    !write_index_ext_header(&c, newfd, CACHE_EXT_TREE, sz) &&
-		    !ce_write(&c, newfd, data, sz))
-			free(data);
-		else {
-			free(data);
+		struct strbuf sb;
+
+		strbuf_init(&sb, 0);
+		cache_tree_write(&sb, istate->cache_tree);
+		err = write_index_ext_header(&c, newfd, CACHE_EXT_TREE, sb.len) < 0
+			|| ce_write(&c, newfd, sb.buf, sb.len) < 0;
+		strbuf_release(&sb);
+		if (err)
 			return -1;
-		}
 	}
 	return ce_flush(&c, newfd);
 }
-- 
1.5.3.2.1067.g96579-dirty

^ permalink raw reply related

* Re: [PATCH] unexpected Make output (e.g. from --debug) causes build failure
From: David Kastrup @ 2007-09-25  7:59 UTC (permalink / raw)
  To: git
In-Reply-To: <877imftfef.fsf@rho.meyering.net>

Jim Meyering <jim@meyering.net> writes:

> Without this, the extra output produced e.g., by "make --debug"
> would go into $INSTLIBDIR and then cause the sed command to fail.
>
> Signed-off-by: Jim Meyering <jim@meyering.net>
> ---
>  Makefile |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/Makefile b/Makefile
> index 0055eef..97ce687 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -805,7 +805,7 @@ perl/perl.mak: GIT-CFLAGS
>
>  $(patsubst %.perl,%,$(SCRIPT_PERL)): % : %.perl
>  	$(QUIET_GEN)$(RM) $@ $@+ && \
> -	INSTLIBDIR=`$(MAKE) -C perl -s --no-print-directory instlibdir` && \
> +	INSTLIBDIR=`MAKEFLAGS= $(MAKE) -C perl -s --no-print-directory instlibdir` && \
>  	sed -e '1{' \
>  	    -e '	s|#!.*perl|#!$(PERL_PATH_SQ)|' \
>  	    -e '	h' \
> --
> 1.5.3.2.99.ge4b2-dirty

Does this work with "make -n" ?

-- 
David Kastrup

^ permalink raw reply

* [PATCH] Do not over-quote the -f envelopesender value.
From: Jim Meyering @ 2007-09-25  6:48 UTC (permalink / raw)
  To: git


Without this, the value passed to sendmail would have an extra set of
single quotes.  At least exim's sendmail emulation would object to that:

    exim: bad -f address "'list-addr@example.org'": malformed address: ' \
      may not follow 'list-addr@example.org
    error: hooks/post-receive exited with error code 1

Signed-off-by: Jim Meyering <jim@meyering.net>
---
 contrib/hooks/post-receive-email |   16 ++++++++++------
 1 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/contrib/hooks/post-receive-email b/contrib/hooks/post-receive-email
index c589a39..1f88099 100644
--- a/contrib/hooks/post-receive-email
+++ b/contrib/hooks/post-receive-email
@@ -571,6 +571,15 @@ generate_delete_general_email()
 	echo $LOGEND
 }

+send_mail()
+{
+	if [ -n "$envelopesender" ]; then
+		/usr/sbin/sendmail -t -f "$envelopesender"
+	else
+		/usr/sbin/sendmail -t
+	fi
+}
+
 # ---------------------------- main()

 # --- Constants
@@ -607,13 +616,8 @@ if [ -n "$1" -a -n "$2" -a -n "$3" ]; then
 	# resend an email; they could redirect the output to sendmail themselves
 	PAGER= generate_email $2 $3 $1
 else
-	if [ -n "$envelopesender" ]; then
-		envelopesender="-f '$envelopesender'"
-	fi
-
 	while read oldrev newrev refname
 	do
-		generate_email $oldrev $newrev $refname |
-		/usr/sbin/sendmail -t $envelopesender
+		generate_email $oldrev $newrev $refname | send_mail
 	done
 fi
--
1.5.3.2.99.ge4b2-dirty

^ permalink raw reply related

* [PATCH] unexpected Make output (e.g. from --debug) causes build failure
From: Jim Meyering @ 2007-09-25  6:42 UTC (permalink / raw)
  To: git

Without this, the extra output produced e.g., by "make --debug"
would go into $INSTLIBDIR and then cause the sed command to fail.

Signed-off-by: Jim Meyering <jim@meyering.net>
---
 Makefile |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/Makefile b/Makefile
index 0055eef..97ce687 100644
--- a/Makefile
+++ b/Makefile
@@ -805,7 +805,7 @@ perl/perl.mak: GIT-CFLAGS

 $(patsubst %.perl,%,$(SCRIPT_PERL)): % : %.perl
 	$(QUIET_GEN)$(RM) $@ $@+ && \
-	INSTLIBDIR=`$(MAKE) -C perl -s --no-print-directory instlibdir` && \
+	INSTLIBDIR=`MAKEFLAGS= $(MAKE) -C perl -s --no-print-directory instlibdir` && \
 	sed -e '1{' \
 	    -e '	s|#!.*perl|#!$(PERL_PATH_SQ)|' \
 	    -e '	h' \
--
1.5.3.2.99.ge4b2-dirty

^ permalink raw reply related

* Re: [PATCH] git-submodule - allow a relative path as the subproject url
From: Junio C Hamano @ 2007-09-25  6:42 UTC (permalink / raw)
  To: Mark Levedahl; +Cc: git
In-Reply-To: <1190600382-1648-1-git-send-email-mdl123@verizon.net>

Mark Levedahl <mdl123@verizon.net> writes:

> This allows a subproject's location to be specified and stored as relative
> to the parent project's location (e.g., ./foo, or ../foo). This url is
> stored in .gitmodules as given. It is resolved into an absolute url by
> appending it to the parent project's url when the information is written
> to .git/config (i.e., during submodule add for the originator, and
> submodule init for a downstream recipient). This allows cloning of the
> project to work "as expected" if the project is hosted on a different
> server than when the subprojects were added.
>
> Signed-off-by: Mark Levedahl <mdl123@verizon.net>

I like the idea here.  If you maintain and serve a set related
projects you need to give the users a single URL (per where the
user is and how to reach the server).

> diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt
> index 2c48936..d421677 100644
> --- a/Documentation/git-submodule.txt
> +++ b/Documentation/git-submodule.txt
> @@ -21,6 +21,9 @@ add::
>  	repository is cloned at the specified path, added to the
>  	changeset and registered in .gitmodules.   If no path is
>  	specified, the path is deduced from the repository specification.
> +        If the repository url begins with ./ or ../, it is stored as
> +        given but resolved as a relative path from the main project's
> +        url when cloning.

Tabs vs spaces?  Will fix up while applying.

Thanks.

^ permalink raw reply

* [PATCH] Make merge-recursive honor diff.renamelimit
From: Lars Hjemli @ 2007-09-25  6:36 UTC (permalink / raw)
  To: Junio C Hamano, Linus Torvalds; +Cc: git

It might be a sign of source code management gone bad, but when two branches
has diverged almost beyond recognition and time has come for the branches to
merge, the user is going to need all the help his tool can give him. Honoring
diff.renamelimit has great potential as a painkiller in such situations.

The painkiller effect could have been achieved by e.g. 'merge.renamelimit',
but the flexibility gained by a separate option is questionable: our user
would probably expect git to detect renames equally good when merging as
when diffing (I known I did).

Signed-off-by: Lars Hjemli <hjemli@gmail.com>
---


On 9/14/07, Linus Torvalds <torvalds@linux-foundation.org> wrote:
> 
> The choice of default value is of course very debatable. Limiting the
> rename matrix to a 100x100 size will mean that even if you have just one
> obvious rename, but you also create (or delete) 10,000 files, the rename
> matrix will be so big that we disable the heuristics. Sounds reasonable to
> me, but let's see if people hit this (and, perhaps more importantly,
> actually *care*) in real life.

Yeah, I got hit, and I care ;-)


 merge-recursive.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/merge-recursive.c b/merge-recursive.c
index 19d5f3b..97dcf9b 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -96,6 +96,7 @@ static struct path_list current_directory_set = {NULL, 0, 0, 1};
 
 static int call_depth = 0;
 static int verbosity = 2;
+static int rename_limit = -1;
 static int buffer_output = 1;
 static struct output_buffer *output_list, *output_end;
 
@@ -372,6 +373,7 @@ static struct path_list *get_renames(struct tree *tree,
 	diff_setup(&opts);
 	opts.recursive = 1;
 	opts.detect_rename = DIFF_DETECT_RENAME;
+	opts.rename_limit = rename_limit;
 	opts.output_format = DIFF_FORMAT_NO_OUTPUT;
 	if (diff_setup_done(&opts) < 0)
 		die("diff setup failed");
@@ -1693,6 +1695,10 @@ static int merge_config(const char *var, const char *value)
 		verbosity = git_config_int(var, value);
 		return 0;
 	}
+	if (!strcasecmp(var, "diff.renamelimit")) {
+		rename_limit = git_config_int(var, value);
+		return 0;
+	}
 	return git_default_config(var, value);
 }
 
-- 
1.5.3.2.1054.g35b0b

^ permalink raw reply related

* Re: [PATCH] Supplant the "while case ... break ;; esac" idiom
From: Junio C Hamano @ 2007-09-25  6:29 UTC (permalink / raw)
  To: David Kastrup; +Cc: git
In-Reply-To: <85hcljgtlr.fsf@lola.goethe.zz>

David Kastrup <dak@gnu.org> writes:

> As a completely irrelevant side note: the autoconf documentation
> mentions that "false" is more portable than "true" since calling it
> returns a non-zero exit status even when it is not installed or
> built-in.

Ah, I like that ;-)  It is obvious when you think about it, and
it is so true but in a very twisted way...

^ permalink raw reply

* Re: [PATCH] Add ability to specify SMTP server port when using git-send-email.
From: Junio C Hamano @ 2007-09-25  6:24 UTC (permalink / raw)
  To: Glenn Rempe; +Cc: git
In-Reply-To: <1190666058-10969-1-git-send-email-glenn@rempe.us>

Glenn Rempe <glenn@rempe.us> writes:

>  git-send-email.perl |   48 +++++++++++++++++++++++++++++++++++++-----------
>  1 files changed, 37 insertions(+), 11 deletions(-)
>
> diff --git a/git-send-email.perl b/git-send-email.perl
> index 4031e86..7c9c302 100755
> --- a/git-send-email.perl
> +++ b/git-send-email.perl
> @@ -79,6 +79,10 @@ Options:
>     --smtp-server  If set, specifies the outgoing SMTP server to use.
>                    Defaults to localhost.
>  
> +   --smtp-server-port If set, specifies the port on the outgoing SMTP
> +   server to use. Defaults to port 25 unless --smtp-ssl is set in
> +   which case it will default to port 465.
> +

This paragraph look inconsistent with different indentation
for second and subsequent lines.

> @@ -375,6 +381,14 @@ if (!defined $smtp_server) {
>  	$smtp_server ||= 'localhost'; # could be 127.0.0.1, too... *shrug*
>  }
>  
> +if (!defined $smtp_server_port) {
> +  if ($smtp_ssl) {
> +    $smtp_server_port = 465  # SSL port
> +  } else {
> +    $smtp_server_port = 25  # Non-SSL port
> +  }
> +}
> +
>  if ($compose) {
>  	# Note that this does not need to be secure, but we will make a small
>  	# effort to have it be unique
> @@ -604,20 +618,32 @@ X-Mailer: git-send-email $gitversion
>  	} else {
>  		if ($smtp_ssl) {
>  			require Net::SMTP::SSL;
> -			$smtp ||= Net::SMTP::SSL->new( $smtp_server, Port => 465 );
> +			$smtp ||= Net::SMTP::SSL->new( $smtp_server, Port => $smtp_server_port );
>  		}
>  		else {
>  			require Net::SMTP;
> -			$smtp ||= Net::SMTP->new( $smtp_server );
> +			$smtp ||= Net::SMTP->new( $smtp_server . ":" . $smtp_server_port );
>  		}

This change suggests that, although undocumented, existing users
could have already been using

	--smtp-server=smtp.myisp.com:26

to specify a nonstandard port, and this patch, while bringing in
the support for a nonstandard port as an official feature, would
break such a setup.  I wonder how real the issue is, and if we
can work it around easily.  For example,

 (1) drop the "default to 25 for smtp if undefined" part we saw
     earlier;

 (2) redo this part as

	if ($smtp_ssl) {
		... as you have it ...
	} else {
		require Net::SMTP;
                $smtp ||= Net::SMTP->new((defined $smtp_server_port) ?
					 "$smtp_server:$smtp_server_port" :
                                         $smtp_server);
	}

> -		$smtp->auth( $smtp_authuser, $smtp_authpass )
> -			or die $smtp->message if (defined $smtp_authuser);
> ...
> +    
> +    # we'll get an ugly error if $smtp was undefined above.
> +    # If so we'll catch it and present something friendlier.
> +    if ($smtp) {
> +
> +      if ((defined $smtp_authuser) && (defined $smtp_authpass)) {
> +        $smtp->auth( $smtp_authuser, $smtp_authpass ) or die $smtp->message;
> +      }
> +    ...
> +    } else {
> +      die "Unable to initialize SMTP properly.  Is there something wrong with your config?";
> +    }


I'd prefer the check done the opposite order, like

	if (!$smtp) {
        	die ...
	}

without an else clause.

^ permalink raw reply

* Re: [PATCH] Supplant the "while case ... break ;; esac" idiom
From: David Kastrup @ 2007-09-25  6:13 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vodfr8wts.fsf@gitster.siamese.dyndns.org>

Junio C Hamano <gitster@pobox.com> writes:

> David Kastrup <dak@gnu.org> writes:
>
>> I am somewhat taken aback that a commit message considered offensive
>> (though I still have a problem understanding why and certainly did not
>> intend this) has been committed into master without giving me a chance
>> to amend it.
>
> Heh, that's simple.  I changed my mind ;-)
>
> When A and B test for preconditions, and C, D, and E are
> operations with error reports as their side effects, we can
> write our loop in these forms:
>
>  (1) while A && B && C && D && E || false; do :; done
>  (2) while A && B && C && D && E || break; do :; done
>  (3) while A && B; do C && D && E || break; do :; done
>  (4) while :; do A && B && C && D && E || break; done
>
> and all of them are equivalent.
>
> But obviously the only sane version is (3).

Uh, it is the only version with a syntax error.

> If your complaint were against things like (1) and (2), I would have
> completely agreed with you.  If you want "effects", you do so
> between do and done.  Although you can use break between do and done
> if you need to conditionally break out of the loop after causing
> some effect there, between while and do is where you are only
> supposed to decide if you want to break out of the loop without
> causing "effects".
>
> But what you were complaining about was different.

Basically

while A && B || break; do C && D && E || break; done

> If we were to ignore broken shells that do not return success
> from a case statement with no matching pattern, the following
> two are equivalent:
>
> 	while case "$sth" in foo) break ;; esac; do ...; done
> 	while case "$sth" in foo) false ;; esac; do ...; done
>
> Their "case" are used to decide if you want to break out of the
> loop; the former is (1) being a bit more explicit, and (2) used
> to be a bit more efficient when false was not built-in.

As a completely irrelevant side note: the autoconf documentation
mentions that "false" is more portable than "true" since calling it
returns a non-zero exit status even when it is not installed or
built-in.

> Now the latter reason is mostly historical and it is not a valid
> reason to choose the former over the latter anymore.  But that does
> not make it any more confusing than the latter to a person who knows
> what "break" means in a loop.  An explicit 'break' is still more,
> eh,... explicit ;-)
>
> But the "break" never was the issue.  Return value of "case" was.

I guess this has been a misunderstanding: for me, personally, the
break was the issue: I don't like breaking out of a condition, since
breaking for me is an action.  I just used the fact that the BSD
shells happen not to grok the constructs (and actually through a
somewhat similar confusion between condition and action) to leverage
my dislike of this construct and propose a patch.

> The reason I took your patch and proposed commit log message
> (almost) as-is was because you rewrote "case" to "test".

Uhm, ok.  It was a case of realizing "hm, this does not really look
much nicer" before I chose to switch to "test".  In fact, there is one
case statement remaining which I rewrote in the previously discussed
manner, and it did not strike me as being much prettier.  So maybe I
somewhat misjudged the core of my offended sense of aesthetics, but
the impetus of the discussion still carried into the commit message.

Alea iacta est ("The SHA-1 has been established").

-- 
David Kastrup, Kriemhildstr. 15, 44793 Bochum

^ permalink raw reply

* Re: [PATCH] rebase -i: commit when continuing after "edit"
From: Junio C Hamano @ 2007-09-25  5:37 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Dmitry Potapov, git
In-Reply-To: <Pine.LNX.4.64.0709240121080.28395@racer.site>

> When doing an "edit" on a commit, editing and git-adding some files,
> "git rebase -i" complained about a missing "author-script".  The idea was
> that the user would call "git commit --amend" herself.
> 
> But we can be nice and do that for the user.
> 
> To do this, rebase -i stores the author script and message whenever
> writing out a patch, and it remembers to do an "amend" by creating the
> file "amend" in "$DOTEST".
> 
> Noticed by Dmitry Potapov.
> 
> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> Signed-off-by: Junio C Hamano <gitster@pobox.com>
> 
> diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
> index 2fa53fd..5982967 100755
> --- a/git-rebase--interactive.sh
> +++ b/git-rebase--interactive.sh
> @@ -1,484 +1,488 @@
>  #!/bin/sh
> ...
>  output () {
>  	case "$VERBOSE" in
>  	'')
>  		"$@" > "$DOTEST"/output 2>&1
>  		status=$?
>  		test $status != 0 &&
>  			cat "$DOTEST"/output
>  		return $status
>  	;;

One more level of indent, please.

>  	*)
>  		"$@"
>  	esac

I find it is usually less error prone to help the longer term
maintainability if you do not omit double-semicolon before esac.

>  }
>  
>  require_clean_work_tree () {
>  	# test if working tree is dirty
>  	git rev-parse --verify HEAD > /dev/null &&
>  	git update-index --refresh &&
>  	git diff-files --quiet &&
>  	git diff-index --cached --quiet HEAD ||
>  	die "Working tree is dirty"
>  }
> ... 
>  mark_action_done () {
>  	sed -e 1q < "$TODO" >> "$DONE"
>  	sed -e 1d < "$TODO" >> "$TODO".new
>  	mv -f "$TODO".new "$TODO"
>  	count=$(($(wc -l < "$DONE")))
>  	total=$(($count+$(wc -l < "$TODO")))
>  	printf "Rebasing (%d/%d)\r" $count $total
>  	test -z "$VERBOSE" || echo
>  }
>  
>  make_patch () {
>  	parent_sha1=$(git rev-parse --verify "$1"^ 2> /dev/null)
>  	git diff "$parent_sha1".."$1" > "$DOTEST"/patch

What's the point of using --verify when you do not error out
upon error?  I find this quite inconsistent; your
require_clean_work_tree above is so nicely written.

Is there anything (other than user's common sense, which we
cannot always count on these days) that prevents the caller to
feed a root commit to this function, I wonder?

> -}
> -
> -die_with_patch () {
>  	test -f "$DOTEST"/message ||
>  		git cat-file commit $sha1 | sed "1,/^$/d" > "$DOTEST"/message
>  	test -f "$DOTEST"/author-script ||
>  		get_author_ident_from_commit $sha1 > "$DOTEST"/author-script
> +}

Are these "$sha1" still valid, or do you need "$1" given to the
make_patch function?

>  pick_one () {
>  	no_ff=
>  	case "$1" in -n) sha1=$2; no_ff=t ;; *) sha1=$1 ;; esac
>  	output git rev-parse --verify $sha1 || die "Invalid commit name: $sha1"
>  	test -d "$REWRITTEN" &&
>  		pick_one_preserving_merges "$@" && return
>  	parent_sha1=$(git rev-parse --verify $sha1^ 2>/dev/null)
>  	current_sha1=$(git rev-parse --verify HEAD)

Again --verify without verifying.

>  	if test $no_ff$current_sha1 = $parent_sha1; then
>  		output git reset --hard $sha1
>  		test "a$1" = a-n && output git reset --soft $current_sha1
>  		sha1=$(git rev-parse --short $sha1)
>  		output warn Fast forward to $sha1
>  	else
>  		output git cherry-pick $STRATEGY "$@"
>  	fi
>  }
>  
>  pick_one_preserving_merges () {
>  	case "$1" in -n) sha1=$2 ;; *) sha1=$1 ;; esac
>  	sha1=$(git rev-parse $sha1)
>  
>  	if test -f "$DOTEST"/current-commit
>  	then
>  		current_commit=$(cat "$DOTEST"/current-commit) &&
>  		git rev-parse HEAD > "$REWRITTEN"/$current_commit &&
>  		rm "$DOTEST"/current-commit ||
>  		die "Cannot write current commit's replacement sha1"
>  	fi
>  
>  	# rewrite parents; if none were rewritten, we can fast-forward.
>  	fast_forward=t
>  	preserve=t
>  	new_parents=
>  	for p in $(git rev-list --parents -1 $sha1 | cut -d\  -f2-)

Just a style nit.  A string literal for a SP is easier to read
if written as a SP inside sq pair (i.e. ' ') not backslash
followed by a SP (i.e. \ ).

>  	do
>  		if test -f "$REWRITTEN"/$p
>  		then
>  			preserve=f
>  			new_p=$(cat "$REWRITTEN"/$p)
>  			test $p != $new_p && fast_forward=f
>  			case "$new_parents" in
>  			*$new_p*)
>  				;; # do nothing; that parent is already there
>  			*)
>  				new_parents="$new_parents $new_p"
>  			esac
>  		fi
>  	done
>  	case $fast_forward in
>  	t)
>  		output warn "Fast forward to $sha1"
>  		test $preserve=f && echo $sha1 > "$REWRITTEN"/$sha1

Testing if concatenation of $preserve and "=f" is not an empty
string, which would almost always yield true?

>  		;;
>  	f)
>  		test "a$1" = a-n && die "Refusing to squash a merge: $sha1"
>  
>  		first_parent=$(expr "$new_parents" : " \([^ ]*\)")

Style; typically regexp form of expr and sed expression are
easier to read with quoted with sq, not dq.

>  		# detach HEAD to current parent
>  		output git checkout $first_parent 2> /dev/null ||
>  			die "Cannot move HEAD to $first_parent"
>  
>  		echo $sha1 > "$DOTEST"/current-commit
>  		case "$new_parents" in
>  		\ *\ *)

Likewise here: ' '*' '*

>  			# redo merge
>  			author_script=$(get_author_ident_from_commit $sha1)
>  			eval "$author_script"
>  			msg="$(git cat-file commit $sha1 | \
>  				sed -e '1,/^$/d' -e "s/[\"\\]/\\\\&/g")"

What's this backquoting about?  Your "output" does not eval (and
it shouldn't), so that's not it.  Working around incompatible
echo that does auto magic used to write MERGE_MSG?  Can we lose
the backquoting by using printf "%s\n" there?

> ...
>  nth_string () {
>  	case "$1" in
>  	*1[0-9]|*[04-9]) echo "$1"th;;
>  	*1) echo "$1"st;;
>  	*2) echo "$1"nd;;
>  	*3) echo "$1"rd;;
>  	esac
>  }

Cute.

> ...
>  do_next () {
>  	test -f "$DOTEST"/message && rm "$DOTEST"/message
>  	test -f "$DOTEST"/author-script && rm "$DOTEST"/author-script
> +	test -f "$DOTEST"/amend && rm "$DOTEST"/amend

As you do not check the error from "rm", how are these different
from rm -f "$DOTEST/frotz"?

>  	read command sha1 rest < "$TODO"
>  	case "$command" in
>  	\#|'')
>  		mark_action_done
>  		;;

Perhaps '#'*?

> ...
>  	edit)
>  		comment_for_reflog edit
>  
>  		mark_action_done
>  		pick_one $sha1 ||
>  			die_with_patch $sha1 "Could not apply $sha1... $rest"
>  		make_patch $sha1
> +		: > "$DOTEST"/amend

Good catch, but ':' is redundant ;-)

>  		warn
>  		warn "You can amend the commit now, with"
>  		warn
>  		warn "	git commit --amend"
>  		warn
>  		exit 0
>  		;;
>  	squash)
>  		comment_for_reflog squash
>  
>  		test -z "$(grep -ve '^$' -e '^#' < $DONE)" &&
>  			die "Cannot 'squash' without a previous commit"

Why "test -z"?  Wouldn't this be equivalent?

	grep -v -q -e '^$' -e '^#' "$DONE" || die ...

>  
>  		mark_action_done
>  		make_squash_message $sha1 > "$MSG"
>  		case "$(peek_next_command)" in
>  		squash)
>  			EDIT_COMMIT=
>  			USE_OUTPUT=output
>  			cp "$MSG" "$SQUASH_MSG"
>  		;;

One more level of indent, please.

>  		*)
>  			EDIT_COMMIT=-e
>  			USE_OUTPUT=
>  			test -f "$SQUASH_MSG" && rm "$SQUASH_MSG"

Again, "test -f && rm"?

> ...
>  		pick_one -n $sha1 || failed=t
>  		author_script=$(get_author_ident_from_commit $sha1)
>  		echo "$author_script" > "$DOTEST"/author-script
>  		case $failed in
>  		f)
>  			# This is like --amend, but with a different message
>  			eval "$author_script"
>  			export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE
>  			$USE_OUTPUT git commit -F "$MSG" $EDIT_COMMIT
>  			;;

The "export" here makes me somewhat nervous -- no chance these
leak into the next round?

> ...
>  		HEAD=$(git rev-parse --verify HEAD) || die "No HEAD?"
>  		UPSTREAM=$(git rev-parse --verify "$1") || die "Invalid base"
>  
>  		test -z "$ONTO" && ONTO=$UPSTREAM
>  
>  		: > "$DOTEST"/interactive || die "Could not mark as interactive"
>  		git symbolic-ref HEAD > "$DOTEST"/head-name ||
>  			die "Could not get HEAD"

It was somewhat annoying that you cannot "rebase -i" the
detached HEAD state.

> ...
>  		cat > "$TODO" << EOF
>  # Rebasing $SHORTUPSTREAM..$SHORTHEAD onto $SHORTONTO
>  #
>  # Commands:
>  #  pick = use commit
>  #  edit = use commit, but stop for amending
>  #  squash = use commit, but meld into previous commit
>  #
>  # If you remove a line here THAT COMMIT WILL BE LOST.
>  #
>  EOF
>  		git rev-list $MERGES_OPTION --pretty=oneline --abbrev-commit \
>  			--abbrev=7 --reverse --left-right --cherry-pick \
>  			$UPSTREAM...$HEAD | \
>  			sed -n "s/^>/pick /p" >> "$TODO"
>  
>  		test -z "$(grep -ve '^$' -e '^#' < $TODO)" &&
>  			die_abort "Nothing to do"

Same comment here as before, and there is another one a few
lines below.  Perhaps a trivial shell function is in order?

^ permalink raw reply

* Re: [PATCH] post-checkout hook, and related docs and tests
From: Andreas Ericsson @ 2007-09-25  4:42 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Josh England, git
In-Reply-To: <7vfy138vql.fsf@gitster.siamese.dyndns.org>

Junio C Hamano wrote:
> "Josh England" <jjengla@sandia.gov> writes:
> 
> But I am obviously not the one who is interested in tracking
> extended attributes attached to git contents, and I do not feel
> too strongly about one way or the other.  I am Ok with it if you
> think "checkout is magical" is easier to teach [*1*].
> 
> [Footnote]
> 
> *1* I actually suspect this might be the case.

I think so too, if nothing else than for the simple reason than that
the hook is called 'post-checkout', so the explanation is likely to
go something like 'the checkout program activates it after having
updated the worktree'.


> I consider that
> per-path checkout from a commit is just a fancy and handy way to
> edit individual files but that probably comes from knowing how
> git works too much and I lost my git virginity too long ago.  A
> pure "user" who types "git checkout commit path" may actively
> expect "checkout" command to do something more magical than
> simply updating the index and the work tree files to a random
> state that happens to match the state recorded in one commit.

Like, run the post-checkout hook? I should think it wouldn't be
too hard to believe it will.

I imagine the people using this feature will be either git-fanatics
that use it for everything and only in their own environment, or
sysadmins that get a handy tool for managing config in a corporate
environment. I wouldn't be surprised if those sysadmins weren't
all too keen on learning the 1001 ways there is to create a file
from a special revision in git (and personally I only knew about 2
of the 4 you listed), so for them there'll most likely *only* be
git-checkout to edit the work-tree.

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

^ permalink raw reply

* [PATCH 3/3] Prevent send-pack from segfaulting when a branch doesn't match
From: Shawn O. Pearce @ 2007-09-25  4:13 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

If `git push url foo` can't find a local branch named foo we can't
match it to any remote branch as the local branch is NULL and its
name is probably at position 0x34 in memory.  On most systems that
isn't a valid address for git-send-pack's virtual address space
and we segfault.

If we can't find a source match and we have no destination we
need to abort the match function early before we try to match the
destination against the remote.

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

diff --git a/remote.c b/remote.c
index 2166a2b..e7d735b 100644
--- a/remote.c
+++ b/remote.c
@@ -610,8 +610,11 @@ static int match_explicit(struct ref *src, struct ref *dst,
 	if (!matched_src)
 		errs = 1;
 
-	if (!dst_value)
+	if (!dst_value) {
+		if (!matched_src)
+			return errs;
 		dst_value = matched_src->name;
+	}
 
 	switch (count_refspec_match(dst_value, dst, &matched_dst)) {
 	case 1:
-- 
1.5.3.2.124.g2456-dirty

^ permalink raw reply related

* [PATCH 2/3] Cleanup unnecessary break in remote.c
From: Shawn O. Pearce @ 2007-09-25  4:13 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

This simple change makes the body of "case 0" easier to read; no
matter what the value of matched_src is we want to break out of
the switch and not fall through.  We only want to display an error
if matched_src is NULL, as this indicates there is no local branch
matching the input.

Also modified the default case's error message so it uses one less
line of text.  Even at 8 column per tab indentation we still don't
break 80 columns with this new formatting.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
 remote.c |    9 +++------
 1 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/remote.c b/remote.c
index ac354f3..2166a2b 100644
--- a/remote.c
+++ b/remote.c
@@ -598,15 +598,12 @@ static int match_explicit(struct ref *src, struct ref *dst,
 		 * way to delete 'other' ref at the remote end.
 		 */
 		matched_src = try_explicit_object_name(rs->src);
-		if (matched_src)
-			break;
-		error("src refspec %s does not match any.",
-		      rs->src);
+		if (!matched_src)
+			error("src refspec %s does not match any.", rs->src);
 		break;
 	default:
 		matched_src = NULL;
-		error("src refspec %s matches more than one.",
-		      rs->src);
+		error("src refspec %s matches more than one.", rs->src);
 		break;
 	}
 
-- 
1.5.3.2.124.g2456-dirty

^ permalink raw reply related

* [PATCH 1/3] Cleanup style nit of 'x == NULL' in remote.c
From: Shawn O. Pearce @ 2007-09-25  4:13 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

Git style tends to prefer "!x" over "x == NULL".  Make it so in
these handful of locations that were not following along.

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

diff --git a/remote.c b/remote.c
index e3c3df5..ac354f3 100644
--- a/remote.c
+++ b/remote.c
@@ -416,7 +416,7 @@ int remote_find_tracking(struct remote *remote, struct refspec *refspec)
 	int i;
 
 	if (find_src) {
-		if (refspec->dst == NULL)
+		if (!refspec->dst)
 			return error("find_tracking: need either src or dst");
 		needle = refspec->dst;
 		result = &refspec->src;
@@ -613,7 +613,7 @@ static int match_explicit(struct ref *src, struct ref *dst,
 	if (!matched_src)
 		errs = 1;
 
-	if (dst_value == NULL)
+	if (!dst_value)
 		dst_value = matched_src->name;
 
 	switch (count_refspec_match(dst_value, dst, &matched_dst)) {
@@ -633,7 +633,7 @@ static int match_explicit(struct ref *src, struct ref *dst,
 		      dst_value);
 		break;
 	}
-	if (errs || matched_dst == NULL)
+	if (errs || !matched_dst)
 		return 1;
 	if (matched_dst->peer_ref) {
 		errs = 1;
-- 
1.5.3.2.124.g2456-dirty

^ permalink raw reply related

* [PATCH] Move convert-objects to contrib.
From: Matt Kraai @ 2007-09-25  3:14 UTC (permalink / raw)
  To: git; +Cc: Matt Kraai


Signed-off-by: Matt Kraai <kraai@ftbfs.org>
---
 .gitignore                                      |    1 -
 Documentation/cmd-list.perl                     |    1 -
 Documentation/git-convert-objects.txt           |   28 --
 Makefile                                        |    2 +-
 contrib/completion/git-completion.bash          |    1 -
 contrib/convert-objects/convert-objects.c       |  329 +++++++++++++++++++++++
 contrib/convert-objects/git-convert-objects.txt |   28 ++
 convert-objects.c                               |  329 -----------------------
 8 files changed, 358 insertions(+), 361 deletions(-)
 delete mode 100644 Documentation/git-convert-objects.txt
 create mode 100644 contrib/convert-objects/convert-objects.c
 create mode 100644 contrib/convert-objects/git-convert-objects.txt
 delete mode 100644 convert-objects.c

diff --git a/.gitignore b/.gitignore
index 63c918c..e0b91be 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,7 +25,6 @@ git-clone
 git-commit
 git-commit-tree
 git-config
-git-convert-objects
 git-count-objects
 git-cvsexportcommit
 git-cvsimport
diff --git a/Documentation/cmd-list.perl b/Documentation/cmd-list.perl
index 4ee76ea..1061fd8 100755
--- a/Documentation/cmd-list.perl
+++ b/Documentation/cmd-list.perl
@@ -94,7 +94,6 @@ git-clone                               mainporcelain
 git-commit                              mainporcelain
 git-commit-tree                         plumbingmanipulators
 git-config                              ancillarymanipulators
-git-convert-objects                     ancillarymanipulators
 git-count-objects                       ancillaryinterrogators
 git-cvsexportcommit                     foreignscminterface
 git-cvsimport                           foreignscminterface
diff --git a/Documentation/git-convert-objects.txt b/Documentation/git-convert-objects.txt
deleted file mode 100644
index 9718abf..0000000
--- a/Documentation/git-convert-objects.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-git-convert-objects(1)
-======================
-
-NAME
-----
-git-convert-objects - Converts old-style git repository
-
-
-SYNOPSIS
---------
-'git-convert-objects'
-
-DESCRIPTION
------------
-Converts old-style git repository to the latest format
-
-
-Author
-------
-Written by Linus Torvalds <torvalds@osdl.org>
-
-Documentation
---------------
-Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel.org>.
-
-GIT
----
-Part of the gitlink:git[7] suite
diff --git a/Makefile b/Makefile
index 0055eef..94b16d0 100644
--- a/Makefile
+++ b/Makefile
@@ -233,7 +233,7 @@ SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH)) \
 
 # ... and all the rest that could be moved out of bindir to gitexecdir
 PROGRAMS = \
-	git-convert-objects$X git-fetch-pack$X \
+	git-fetch-pack$X \
 	git-hash-object$X git-index-pack$X git-local-fetch$X \
 	git-fast-import$X \
 	git-daemon$X \
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index cad842a..e760930 100755
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -299,7 +299,6 @@ __git_commands ()
 		check-attr)       : plumbing;;
 		check-ref-format) : plumbing;;
 		commit-tree)      : plumbing;;
-		convert-objects)  : plumbing;;
 		cvsexportcommit)  : export;;
 		cvsimport)        : import;;
 		cvsserver)        : daemon;;
diff --git a/contrib/convert-objects/convert-objects.c b/contrib/convert-objects/convert-objects.c
new file mode 100644
index 0000000..90e7900
--- /dev/null
+++ b/contrib/convert-objects/convert-objects.c
@@ -0,0 +1,329 @@
+#include "cache.h"
+#include "blob.h"
+#include "commit.h"
+#include "tree.h"
+
+struct entry {
+	unsigned char old_sha1[20];
+	unsigned char new_sha1[20];
+	int converted;
+};
+
+#define MAXOBJECTS (1000000)
+
+static struct entry *convert[MAXOBJECTS];
+static int nr_convert;
+
+static struct entry * convert_entry(unsigned char *sha1);
+
+static struct entry *insert_new(unsigned char *sha1, int pos)
+{
+	struct entry *new = xcalloc(1, sizeof(struct entry));
+	hashcpy(new->old_sha1, sha1);
+	memmove(convert + pos + 1, convert + pos, (nr_convert - pos) * sizeof(struct entry *));
+	convert[pos] = new;
+	nr_convert++;
+	if (nr_convert == MAXOBJECTS)
+		die("you're kidding me - hit maximum object limit");
+	return new;
+}
+
+static struct entry *lookup_entry(unsigned char *sha1)
+{
+	int low = 0, high = nr_convert;
+
+	while (low < high) {
+		int next = (low + high) / 2;
+		struct entry *n = convert[next];
+		int cmp = hashcmp(sha1, n->old_sha1);
+		if (!cmp)
+			return n;
+		if (cmp < 0) {
+			high = next;
+			continue;
+		}
+		low = next+1;
+	}
+	return insert_new(sha1, low);
+}
+
+static void convert_binary_sha1(void *buffer)
+{
+	struct entry *entry = convert_entry(buffer);
+	hashcpy(buffer, entry->new_sha1);
+}
+
+static void convert_ascii_sha1(void *buffer)
+{
+	unsigned char sha1[20];
+	struct entry *entry;
+
+	if (get_sha1_hex(buffer, sha1))
+		die("expected sha1, got '%s'", (char*) buffer);
+	entry = convert_entry(sha1);
+	memcpy(buffer, sha1_to_hex(entry->new_sha1), 40);
+}
+
+static unsigned int convert_mode(unsigned int mode)
+{
+	unsigned int newmode;
+
+	newmode = mode & S_IFMT;
+	if (S_ISREG(mode))
+		newmode |= (mode & 0100) ? 0755 : 0644;
+	return newmode;
+}
+
+static int write_subdirectory(void *buffer, unsigned long size, const char *base, int baselen, unsigned char *result_sha1)
+{
+	char *new = xmalloc(size);
+	unsigned long newlen = 0;
+	unsigned long used;
+
+	used = 0;
+	while (size) {
+		int len = 21 + strlen(buffer);
+		char *path = strchr(buffer, ' ');
+		unsigned char *sha1;
+		unsigned int mode;
+		char *slash, *origpath;
+
+		if (!path || strtoul_ui(buffer, 8, &mode))
+			die("bad tree conversion");
+		mode = convert_mode(mode);
+		path++;
+		if (memcmp(path, base, baselen))
+			break;
+		origpath = path;
+		path += baselen;
+		slash = strchr(path, '/');
+		if (!slash) {
+			newlen += sprintf(new + newlen, "%o %s", mode, path);
+			new[newlen++] = '\0';
+			hashcpy((unsigned char*)new + newlen, (unsigned char *) buffer + len - 20);
+			newlen += 20;
+
+			used += len;
+			size -= len;
+			buffer = (char *) buffer + len;
+			continue;
+		}
+
+		newlen += sprintf(new + newlen, "%o %.*s", S_IFDIR, (int)(slash - path), path);
+		new[newlen++] = 0;
+		sha1 = (unsigned char *)(new + newlen);
+		newlen += 20;
+
+		len = write_subdirectory(buffer, size, origpath, slash-origpath+1, sha1);
+
+		used += len;
+		size -= len;
+		buffer = (char *) buffer + len;
+	}
+
+	write_sha1_file(new, newlen, tree_type, result_sha1);
+	free(new);
+	return used;
+}
+
+static void convert_tree(void *buffer, unsigned long size, unsigned char *result_sha1)
+{
+	void *orig_buffer = buffer;
+	unsigned long orig_size = size;
+
+	while (size) {
+		size_t len = 1+strlen(buffer);
+
+		convert_binary_sha1((char *) buffer + len);
+
+		len += 20;
+		if (len > size)
+			die("corrupt tree object");
+		size -= len;
+		buffer = (char *) buffer + len;
+	}
+
+	write_subdirectory(orig_buffer, orig_size, "", 0, result_sha1);
+}
+
+static unsigned long parse_oldstyle_date(const char *buf)
+{
+	char c, *p;
+	char buffer[100];
+	struct tm tm;
+	const char *formats[] = {
+		"%c",
+		"%a %b %d %T",
+		"%Z",
+		"%Y",
+		" %Y",
+		NULL
+	};
+	/* We only ever did two timezones in the bad old format .. */
+	const char *timezones[] = {
+		"PDT", "PST", "CEST", NULL
+	};
+	const char **fmt = formats;
+
+	p = buffer;
+	while (isspace(c = *buf))
+		buf++;
+	while ((c = *buf++) != '\n')
+		*p++ = c;
+	*p++ = 0;
+	buf = buffer;
+	memset(&tm, 0, sizeof(tm));
+	do {
+		const char *next = strptime(buf, *fmt, &tm);
+		if (next) {
+			if (!*next)
+				return mktime(&tm);
+			buf = next;
+		} else {
+			const char **p = timezones;
+			while (isspace(*buf))
+				buf++;
+			while (*p) {
+				if (!memcmp(buf, *p, strlen(*p))) {
+					buf += strlen(*p);
+					break;
+				}
+				p++;
+			}
+		}
+		fmt++;
+	} while (*buf && *fmt);
+	printf("left: %s\n", buf);
+	return mktime(&tm);
+}
+
+static int convert_date_line(char *dst, void **buf, unsigned long *sp)
+{
+	unsigned long size = *sp;
+	char *line = *buf;
+	char *next = strchr(line, '\n');
+	char *date = strchr(line, '>');
+	int len;
+
+	if (!next || !date)
+		die("missing or bad author/committer line %s", line);
+	next++; date += 2;
+
+	*buf = next;
+	*sp = size - (next - line);
+
+	len = date - line;
+	memcpy(dst, line, len);
+	dst += len;
+
+	/* Is it already in new format? */
+	if (isdigit(*date)) {
+		int datelen = next - date;
+		memcpy(dst, date, datelen);
+		return len + datelen;
+	}
+
+	/*
+	 * Hacky hacky: one of the sparse old-style commits does not have
+	 * any date at all, but we can fake it by using the committer date.
+	 */
+	if (*date == '\n' && strchr(next, '>'))
+		date = strchr(next, '>')+2;
+
+	return len + sprintf(dst, "%lu -0700\n", parse_oldstyle_date(date));
+}
+
+static void convert_date(void *buffer, unsigned long size, unsigned char *result_sha1)
+{
+	char *new = xmalloc(size + 100);
+	unsigned long newlen = 0;
+
+	/* "tree <sha1>\n" */
+	memcpy(new + newlen, buffer, 46);
+	newlen += 46;
+	buffer = (char *) buffer + 46;
+	size -= 46;
+
+	/* "parent <sha1>\n" */
+	while (!memcmp(buffer, "parent ", 7)) {
+		memcpy(new + newlen, buffer, 48);
+		newlen += 48;
+		buffer = (char *) buffer + 48;
+		size -= 48;
+	}
+
+	/* "author xyz <xyz> date" */
+	newlen += convert_date_line(new + newlen, &buffer, &size);
+	/* "committer xyz <xyz> date" */
+	newlen += convert_date_line(new + newlen, &buffer, &size);
+
+	/* Rest */
+	memcpy(new + newlen, buffer, size);
+	newlen += size;
+
+	write_sha1_file(new, newlen, commit_type, result_sha1);
+	free(new);
+}
+
+static void convert_commit(void *buffer, unsigned long size, unsigned char *result_sha1)
+{
+	void *orig_buffer = buffer;
+	unsigned long orig_size = size;
+
+	if (memcmp(buffer, "tree ", 5))
+		die("Bad commit '%s'", (char*) buffer);
+	convert_ascii_sha1((char *) buffer + 5);
+	buffer = (char *) buffer + 46;    /* "tree " + "hex sha1" + "\n" */
+	while (!memcmp(buffer, "parent ", 7)) {
+		convert_ascii_sha1((char *) buffer + 7);
+		buffer = (char *) buffer + 48;
+	}
+	convert_date(orig_buffer, orig_size, result_sha1);
+}
+
+static struct entry * convert_entry(unsigned char *sha1)
+{
+	struct entry *entry = lookup_entry(sha1);
+	enum object_type type;
+	void *buffer, *data;
+	unsigned long size;
+
+	if (entry->converted)
+		return entry;
+	data = read_sha1_file(sha1, &type, &size);
+	if (!data)
+		die("unable to read object %s", sha1_to_hex(sha1));
+
+	buffer = xmalloc(size);
+	memcpy(buffer, data, size);
+
+	if (type == OBJ_BLOB) {
+		write_sha1_file(buffer, size, blob_type, entry->new_sha1);
+	} else if (type == OBJ_TREE)
+		convert_tree(buffer, size, entry->new_sha1);
+	else if (type == OBJ_COMMIT)
+		convert_commit(buffer, size, entry->new_sha1);
+	else
+		die("unknown object type %d in %s", type, sha1_to_hex(sha1));
+	entry->converted = 1;
+	free(buffer);
+	free(data);
+	return entry;
+}
+
+int main(int argc, char **argv)
+{
+	unsigned char sha1[20];
+	struct entry *entry;
+
+	setup_git_directory();
+
+	if (argc != 2)
+		usage("git-convert-objects <sha1>");
+	if (get_sha1(argv[1], sha1))
+		die("Not a valid object name %s", argv[1]);
+
+	entry = convert_entry(sha1);
+	printf("new sha1: %s\n", sha1_to_hex(entry->new_sha1));
+	return 0;
+}
diff --git a/contrib/convert-objects/git-convert-objects.txt b/contrib/convert-objects/git-convert-objects.txt
new file mode 100644
index 0000000..9718abf
--- /dev/null
+++ b/contrib/convert-objects/git-convert-objects.txt
@@ -0,0 +1,28 @@
+git-convert-objects(1)
+======================
+
+NAME
+----
+git-convert-objects - Converts old-style git repository
+
+
+SYNOPSIS
+--------
+'git-convert-objects'
+
+DESCRIPTION
+-----------
+Converts old-style git repository to the latest format
+
+
+Author
+------
+Written by Linus Torvalds <torvalds@osdl.org>
+
+Documentation
+--------------
+Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel.org>.
+
+GIT
+---
+Part of the gitlink:git[7] suite
diff --git a/convert-objects.c b/convert-objects.c
deleted file mode 100644
index 90e7900..0000000
--- a/convert-objects.c
+++ /dev/null
@@ -1,329 +0,0 @@
-#include "cache.h"
-#include "blob.h"
-#include "commit.h"
-#include "tree.h"
-
-struct entry {
-	unsigned char old_sha1[20];
-	unsigned char new_sha1[20];
-	int converted;
-};
-
-#define MAXOBJECTS (1000000)
-
-static struct entry *convert[MAXOBJECTS];
-static int nr_convert;
-
-static struct entry * convert_entry(unsigned char *sha1);
-
-static struct entry *insert_new(unsigned char *sha1, int pos)
-{
-	struct entry *new = xcalloc(1, sizeof(struct entry));
-	hashcpy(new->old_sha1, sha1);
-	memmove(convert + pos + 1, convert + pos, (nr_convert - pos) * sizeof(struct entry *));
-	convert[pos] = new;
-	nr_convert++;
-	if (nr_convert == MAXOBJECTS)
-		die("you're kidding me - hit maximum object limit");
-	return new;
-}
-
-static struct entry *lookup_entry(unsigned char *sha1)
-{
-	int low = 0, high = nr_convert;
-
-	while (low < high) {
-		int next = (low + high) / 2;
-		struct entry *n = convert[next];
-		int cmp = hashcmp(sha1, n->old_sha1);
-		if (!cmp)
-			return n;
-		if (cmp < 0) {
-			high = next;
-			continue;
-		}
-		low = next+1;
-	}
-	return insert_new(sha1, low);
-}
-
-static void convert_binary_sha1(void *buffer)
-{
-	struct entry *entry = convert_entry(buffer);
-	hashcpy(buffer, entry->new_sha1);
-}
-
-static void convert_ascii_sha1(void *buffer)
-{
-	unsigned char sha1[20];
-	struct entry *entry;
-
-	if (get_sha1_hex(buffer, sha1))
-		die("expected sha1, got '%s'", (char*) buffer);
-	entry = convert_entry(sha1);
-	memcpy(buffer, sha1_to_hex(entry->new_sha1), 40);
-}
-
-static unsigned int convert_mode(unsigned int mode)
-{
-	unsigned int newmode;
-
-	newmode = mode & S_IFMT;
-	if (S_ISREG(mode))
-		newmode |= (mode & 0100) ? 0755 : 0644;
-	return newmode;
-}
-
-static int write_subdirectory(void *buffer, unsigned long size, const char *base, int baselen, unsigned char *result_sha1)
-{
-	char *new = xmalloc(size);
-	unsigned long newlen = 0;
-	unsigned long used;
-
-	used = 0;
-	while (size) {
-		int len = 21 + strlen(buffer);
-		char *path = strchr(buffer, ' ');
-		unsigned char *sha1;
-		unsigned int mode;
-		char *slash, *origpath;
-
-		if (!path || strtoul_ui(buffer, 8, &mode))
-			die("bad tree conversion");
-		mode = convert_mode(mode);
-		path++;
-		if (memcmp(path, base, baselen))
-			break;
-		origpath = path;
-		path += baselen;
-		slash = strchr(path, '/');
-		if (!slash) {
-			newlen += sprintf(new + newlen, "%o %s", mode, path);
-			new[newlen++] = '\0';
-			hashcpy((unsigned char*)new + newlen, (unsigned char *) buffer + len - 20);
-			newlen += 20;
-
-			used += len;
-			size -= len;
-			buffer = (char *) buffer + len;
-			continue;
-		}
-
-		newlen += sprintf(new + newlen, "%o %.*s", S_IFDIR, (int)(slash - path), path);
-		new[newlen++] = 0;
-		sha1 = (unsigned char *)(new + newlen);
-		newlen += 20;
-
-		len = write_subdirectory(buffer, size, origpath, slash-origpath+1, sha1);
-
-		used += len;
-		size -= len;
-		buffer = (char *) buffer + len;
-	}
-
-	write_sha1_file(new, newlen, tree_type, result_sha1);
-	free(new);
-	return used;
-}
-
-static void convert_tree(void *buffer, unsigned long size, unsigned char *result_sha1)
-{
-	void *orig_buffer = buffer;
-	unsigned long orig_size = size;
-
-	while (size) {
-		size_t len = 1+strlen(buffer);
-
-		convert_binary_sha1((char *) buffer + len);
-
-		len += 20;
-		if (len > size)
-			die("corrupt tree object");
-		size -= len;
-		buffer = (char *) buffer + len;
-	}
-
-	write_subdirectory(orig_buffer, orig_size, "", 0, result_sha1);
-}
-
-static unsigned long parse_oldstyle_date(const char *buf)
-{
-	char c, *p;
-	char buffer[100];
-	struct tm tm;
-	const char *formats[] = {
-		"%c",
-		"%a %b %d %T",
-		"%Z",
-		"%Y",
-		" %Y",
-		NULL
-	};
-	/* We only ever did two timezones in the bad old format .. */
-	const char *timezones[] = {
-		"PDT", "PST", "CEST", NULL
-	};
-	const char **fmt = formats;
-
-	p = buffer;
-	while (isspace(c = *buf))
-		buf++;
-	while ((c = *buf++) != '\n')
-		*p++ = c;
-	*p++ = 0;
-	buf = buffer;
-	memset(&tm, 0, sizeof(tm));
-	do {
-		const char *next = strptime(buf, *fmt, &tm);
-		if (next) {
-			if (!*next)
-				return mktime(&tm);
-			buf = next;
-		} else {
-			const char **p = timezones;
-			while (isspace(*buf))
-				buf++;
-			while (*p) {
-				if (!memcmp(buf, *p, strlen(*p))) {
-					buf += strlen(*p);
-					break;
-				}
-				p++;
-			}
-		}
-		fmt++;
-	} while (*buf && *fmt);
-	printf("left: %s\n", buf);
-	return mktime(&tm);
-}
-
-static int convert_date_line(char *dst, void **buf, unsigned long *sp)
-{
-	unsigned long size = *sp;
-	char *line = *buf;
-	char *next = strchr(line, '\n');
-	char *date = strchr(line, '>');
-	int len;
-
-	if (!next || !date)
-		die("missing or bad author/committer line %s", line);
-	next++; date += 2;
-
-	*buf = next;
-	*sp = size - (next - line);
-
-	len = date - line;
-	memcpy(dst, line, len);
-	dst += len;
-
-	/* Is it already in new format? */
-	if (isdigit(*date)) {
-		int datelen = next - date;
-		memcpy(dst, date, datelen);
-		return len + datelen;
-	}
-
-	/*
-	 * Hacky hacky: one of the sparse old-style commits does not have
-	 * any date at all, but we can fake it by using the committer date.
-	 */
-	if (*date == '\n' && strchr(next, '>'))
-		date = strchr(next, '>')+2;
-
-	return len + sprintf(dst, "%lu -0700\n", parse_oldstyle_date(date));
-}
-
-static void convert_date(void *buffer, unsigned long size, unsigned char *result_sha1)
-{
-	char *new = xmalloc(size + 100);
-	unsigned long newlen = 0;
-
-	/* "tree <sha1>\n" */
-	memcpy(new + newlen, buffer, 46);
-	newlen += 46;
-	buffer = (char *) buffer + 46;
-	size -= 46;
-
-	/* "parent <sha1>\n" */
-	while (!memcmp(buffer, "parent ", 7)) {
-		memcpy(new + newlen, buffer, 48);
-		newlen += 48;
-		buffer = (char *) buffer + 48;
-		size -= 48;
-	}
-
-	/* "author xyz <xyz> date" */
-	newlen += convert_date_line(new + newlen, &buffer, &size);
-	/* "committer xyz <xyz> date" */
-	newlen += convert_date_line(new + newlen, &buffer, &size);
-
-	/* Rest */
-	memcpy(new + newlen, buffer, size);
-	newlen += size;
-
-	write_sha1_file(new, newlen, commit_type, result_sha1);
-	free(new);
-}
-
-static void convert_commit(void *buffer, unsigned long size, unsigned char *result_sha1)
-{
-	void *orig_buffer = buffer;
-	unsigned long orig_size = size;
-
-	if (memcmp(buffer, "tree ", 5))
-		die("Bad commit '%s'", (char*) buffer);
-	convert_ascii_sha1((char *) buffer + 5);
-	buffer = (char *) buffer + 46;    /* "tree " + "hex sha1" + "\n" */
-	while (!memcmp(buffer, "parent ", 7)) {
-		convert_ascii_sha1((char *) buffer + 7);
-		buffer = (char *) buffer + 48;
-	}
-	convert_date(orig_buffer, orig_size, result_sha1);
-}
-
-static struct entry * convert_entry(unsigned char *sha1)
-{
-	struct entry *entry = lookup_entry(sha1);
-	enum object_type type;
-	void *buffer, *data;
-	unsigned long size;
-
-	if (entry->converted)
-		return entry;
-	data = read_sha1_file(sha1, &type, &size);
-	if (!data)
-		die("unable to read object %s", sha1_to_hex(sha1));
-
-	buffer = xmalloc(size);
-	memcpy(buffer, data, size);
-
-	if (type == OBJ_BLOB) {
-		write_sha1_file(buffer, size, blob_type, entry->new_sha1);
-	} else if (type == OBJ_TREE)
-		convert_tree(buffer, size, entry->new_sha1);
-	else if (type == OBJ_COMMIT)
-		convert_commit(buffer, size, entry->new_sha1);
-	else
-		die("unknown object type %d in %s", type, sha1_to_hex(sha1));
-	entry->converted = 1;
-	free(buffer);
-	free(data);
-	return entry;
-}
-
-int main(int argc, char **argv)
-{
-	unsigned char sha1[20];
-	struct entry *entry;
-
-	setup_git_directory();
-
-	if (argc != 2)
-		usage("git-convert-objects <sha1>");
-	if (get_sha1(argv[1], sha1))
-		die("Not a valid object name %s", argv[1]);
-
-	entry = convert_entry(sha1);
-	printf("new sha1: %s\n", sha1_to_hex(entry->new_sha1));
-	return 0;
-}
-- 
1.5.3.2

^ permalink raw reply related

* Re: My stash wants to delete all my files
From: Junio C Hamano @ 2007-09-25  1:26 UTC (permalink / raw)
  To: Jonathan del Strother; +Cc: Git Mailing List
In-Reply-To: <5A9D6E3B-7B0E-4414-9AFB-C1C8B2EE6A9D@steelskies.com>

Jonathan del Strother <maillist@steelskies.com> writes:

> $ git stash list
> stash@{0}: On master: --apply
> stash@{1}: WIP on master: 09e3c30... Better handling of cell sizes in
> the grid
>
> $ git stash show stash@{1}
>  ...
>  19 files changed, 0 insertions(+), 3805 deletions(-)
>
> Hmm.  Looks like it's trying to delete all of my versioned files.
> "git stash apply stash@{1}" confirms this.   Obviously that's not what
> I tried to stash - my WIP when I stashed was a few additions, a couple
> of new unversioned files, and moving a few lines of code from one file
> to another.
>
> Any ideas what happened there?  I can't seem to reproduce the problem
> in a test repository.

There are two possibilities that I can think of offhand, neither
of them is about git-stash but about the state you ran stash
from.

Whenever anybody wonders where inadvertent reverting changes
come from, two most likely reasons are incorrect push into the
current branch's tip initiated from elsewhere, or incorrect
fetch into the current branch's tip initiated from the
repository.

If your work repository is foo, and if you are working on
'master' branch, you could

	$ cd ../bar ; git push ../foo master:master

to push from elsewhere to update the tip of the checked out
branch.  This makes the index and the work tree that was based
on the old commit in foo repository totally out of sync with
respect to the HEAD (which you are replacing), and committing
that state would revert the change the above push made.

You can do the same by doing something equally silly and
destructive by:

	$ git fetch --update-head-ok ../bar master:master

After these operations that could make your index and work
tree state to include reverts, if you "stash", the stash will
record that the reverting was what you wanted to do.

I am not saying this is the only possible explanation though.
You can try:

	git ls-tree stash@{1}
        git rev-parse stash@{1}^1
        git diff stash@{1}^1 stash@{1}^2

The stash entry itself is the state of the work tree, its first
parent (i.e. ^1) is the commit your stash was originally based
on, and its second parent (i.e. ^2) is what was recorded in the
index.  Is the output from the first one empty?  Does the second
command show you that you were on the commit you thought you were
on?  Does the third command show you what you thought you have
told "git add" to put in the index just before you made the
stash?

^ permalink raw reply

* Re: [EGIT PATCH] Change to simplified icon.
From: Shawn O. Pearce @ 2007-09-25  1:16 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0709241124500.28395@racer.site>

Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> On Mon, 24 Sep 2007, Shawn O. Pearce wrote:
> > 
> > [...] Maybe I'll take a stab at creating
> > a git-gui icon [...]
> 
> You might want to look at http://git.or.cz/gitwiki/GitRelatedLogos (I 
> especially like Henrik Nyh's, we use it in git-gui).  Might be a good 
> starting point.

What do you mean you "use it in git-gui" ?  Have you patched git-gui
to set the window icon to Henrik's?  And not tried to contribute
the patch upstream?  Come on, show the GPL love... :-)

-- 
Shawn.

^ permalink raw reply

* Re: Missing strptime
From: Johannes Schindelin @ 2007-09-25  1:03 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: mkraai, git
In-Reply-To: <alpine.LFD.0.999.0709241750510.3579@woody.linux-foundation.org>

Hi,

On Mon, 24 Sep 2007, Linus Torvalds wrote:

> On Tue, 25 Sep 2007, Johannes Schindelin wrote:
> > 
> > The only user for strptime is convert-objects, a program that should 
> > probably move to contrib/ anyway.  It was used once, a long time ago, 
> > to convert from the old format, which hashed the compressed contents, 
> > to the current format, which hashes the contents _before_ compression.
> 
> Actually, it also changes the date format, I think.

Yes, right, that was actually why strptime() was needed.

Ciao,
Dscho

^ permalink raw reply

* Re: Missing strptime
From: Linus Torvalds @ 2007-09-25  0:52 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: mkraai, git
In-Reply-To: <Pine.LNX.4.64.0709250127170.28395@racer.site>



On Tue, 25 Sep 2007, Johannes Schindelin wrote:
> 
> The only user for strptime is convert-objects, a program that should 
> probably move to contrib/ anyway.  It was used once, a long time ago, to 
> convert from the old format, which hashed the compressed contents, to the 
> current format, which hashes the contents _before_ compression.

Actually, it also changes the date format, I think.

> AFAIAC if a similar need should arise, the better alternative would be to 
> write git-fast-export, a tool which dumps the contents of a repository 
> suitable to pipe into git-fast-import.

Agreed. It probably might as well just be moved to contrib and let it 
bitrot.

		Linus

^ permalink raw reply

* Re: Missing strptime
From: Johannes Schindelin @ 2007-09-25  0:30 UTC (permalink / raw)
  To: mkraai; +Cc: git
In-Reply-To: <OF8EBEA0A7.5425E9EA-ON88257360.00812AEA-88257360.00819919@beckman.com>

Hi,

On Mon, 24 Sep 2007, mkraai@beckman.com wrote:

> I'm porting Git to QNX.

That's nice!

> Its C library doesn't provide strptime, so I'd was planning to use the 
> Gnulib implementation.  Is that OK?  If so, should I try to leave it as 
> close to upstream's version as possible or should I remove all of the 
> unneeded cruft?  If not, is there an alternative implementation I should 
> use?

The only user for strptime is convert-objects, a program that should 
probably move to contrib/ anyway.  It was used once, a long time ago, to 
convert from the old format, which hashed the compressed contents, to the 
current format, which hashes the contents _before_ compression.

AFAIAC if a similar need should arise, the better alternative would be to 
write git-fast-export, a tool which dumps the contents of a repository 
suitable to pipe into git-fast-import.

FWIW in mingw.git, we disabled convert-objects already a long time ago.

Ciao,
Dscho

^ permalink raw reply

* Missing strptime
From: mkraai @ 2007-09-24 23:35 UTC (permalink / raw)
  To: git

Howdy,

I'm porting Git to QNX.  Its C library doesn't provide strptime, so I'd 
was planning to use the Gnulib implementation.  Is that OK?  If so, should 
I try to leave it as close to upstream's version as possible or should I 
remove all of the unneeded cruft?  If not, is there an alternative 
implementation I should use?

Matt

P.S. Sorry for the footer.

The server made the following annotations 
---------------------------------------------------------------------------------
This message contains information that may be privileged or confidential and is the property of Beckman Coulter, Inc. It is intended only for the person to whom it is addressed. If you are not the intended recipient, you are not authorized to read, print, retain, copy, disseminate, distribute or use this message or any part thereof. If you receive this message in error, please notify the sender immediately and delete all copies of this message.

---------------------------------------------------------------------------------

^ permalink raw reply

* Re: [PATCH] post-checkout hook, and related docs and tests
From: Junio C Hamano @ 2007-09-24 23:54 UTC (permalink / raw)
  To: Josh England; +Cc: Junio C Hamano, git
In-Reply-To: <1190671558.6078.87.camel@beauty>

"Josh England" <jjengla@sandia.gov> writes:

> On Mon, 2007-09-24 at 14:07 -0700, Junio C Hamano wrote:
> ...
>> If you want to spacial case 
>> 
>>         $ git checkout otherbranch path.c
>> 
>> it raises another issue.  Which commit should supply the
>> "extended attribute description" for path.c?  Should it be taken
>> from the current commit (aka HEAD), otherbranch, or the index?
>
> This already is a special case and your question is valid but not one
> that git should necessary care about.  Since extended attributes are not
> built into git the only way to handle them is through hooks.  A such, it
> is up to the hook to worry about these kinds of issues.

The fear I have is that that kind of thinking would necessitate
your hook to be called after the user edits paths.c in any other
way not to confuse users.

What I am questioning is where we should stop, in order to keep
things simpler to explain, and I happen to think that it is far
easier if we can teach that "git checkout other path.c" is
equivalent to "git cat-file blob other:path.c >path.c" followed
by "git add path.c", than saying "checkout is magical and if you
have external hook it can do far more than editing the file
yourself to arrive at the same contents".

But I am obviously not the one who is interested in tracking
extended attributes attached to git contents, and I do not feel
too strongly about one way or the other.  I am Ok with it if you
think "checkout is magical" is easier to teach [*1*].

I just wanted to make sure we know what semantics this is
bringing in, and get it clearly documented.  That's all.


[Footnote]

*1* I actually suspect this might be the case. I consider that
per-path checkout from a commit is just a fancy and handy way to
edit individual files but that probably comes from knowing how
git works too much and I lost my git virginity too long ago.  A
pure "user" who types "git checkout commit path" may actively
expect "checkout" command to do something more magical than
simply updating the index and the work tree files to a random
state that happens to match the state recorded in one commit.

^ permalink raw reply


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