Git development
 help / color / mirror / Atom feed
* [PATCH] Make git-clone obey "--" (end argument parsing)
From: Heikki Orsila @ 2007-11-01 19:54 UTC (permalink / raw)
  To: git

Oops. Reposting the patch.

This patch handles "--" argument for git-clone.

Signed-off-by: Heikki Orsila <heikki.orsila@iki.fi>

>From bd2d661c565062eacc80dda90f3978303308f9bb Mon Sep 17 00:00:00 2001
From: Heikki Orsila <heikki.orsila@iki.fi>
Date: Thu, 1 Nov 2007 16:21:39 +0200
Subject: [PATCH] Make git-clone obey "--" (end argument parsing)

---
 Documentation/git-clone.txt |    2 +-
 git-clone.sh                |    5 ++++-
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
index 253f4f0..7fdcd42 100644
--- a/Documentation/git-clone.txt
+++ b/Documentation/git-clone.txt
@@ -12,7 +12,7 @@ SYNOPSIS
 'git-clone' [--template=<template_directory>]
 	  [-l] [-s] [--no-hardlinks] [-q] [-n] [--bare]
 	  [-o <name>] [-u <upload-pack>] [--reference <repository>]
-	  [--depth <depth>] <repository> [<directory>]
+	  [--depth <depth>] [--] <repository> [<directory>]
 
 DESCRIPTION
 -----------
diff --git a/git-clone.sh b/git-clone.sh
index 0ea3c24..3f00693 100755
--- a/git-clone.sh
+++ b/git-clone.sh
@@ -14,7 +14,7 @@ die() {
 }
 
 usage() {
-	die "Usage: $0 [--template=<template_directory>] [--reference <reference-repo>] [--bare] [-l [-s]] [-q] [-u <upload-pack>] [--origin <name>] [--depth <n>] [-n] <repo> [<dir>]"
+	die "Usage: $0 [--template=<template_directory>] [--reference <reference-repo>] [--bare] [-l [-s]] [-q] [-u <upload-pack>] [--origin <name>] [--depth <n>] [-n] [--] <repo> [<dir>]"
 }
 
 get_repo_base() {
@@ -160,6 +160,9 @@ while
 	*,--depth)
 		shift
 		depth="--depth=$1";;
+	*,--)
+		shift
+		break ;;
 	*,-*) usage ;;
 	*) break ;;
 	esac
-- 
1.5.3.4.498.g9c514-dirty

^ permalink raw reply related

* Re: [PATCH] Implement git commit as a builtin command.
From: Jakub Narebski @ 2007-11-01 20:14 UTC (permalink / raw)
  To: git
In-Reply-To: <1193944163-22892-1-git-send-email-krh@redhat.com>

Kristian H?gsberg wrote:

> Move git-commit.sh to contrib/examples.

Just a note: you might want to use "git format-patch -M".

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

^ permalink raw reply

* Re: [PATCH 10/10] push: teach push to be quiet if local ref is strict subset of remote ref
From: Junio C Hamano @ 2007-11-01 20:18 UTC (permalink / raw)
  To: Steffen Prohaska; +Cc: Andreas Ericsson, git
In-Reply-To: <3550D197-CA8C-4B06-9A95-3C7F18EBEFA7@zib.de>

Steffen Prohaska <prohaska@zib.de> writes:

> On Nov 1, 2007, at 10:11 AM, Andreas Ericsson wrote:
>
>> Steffen Prohaska wrote:
>>
>>> You're forced to do the integration immediately.

The context of this "forced" is that you say (in the following
paragraph) the user's main objective was to "push", but I do not
think "to push" is ever the main objective.

 - If it is to give integrated result for others to work further
   on, then you need to resolve before being able to achieve
   that goal.  There is no escaping from it.

 - On the other hand, if it is to show what you did as early as
   possible in a working shape, and if the updated shared
   repository has changes from somebody else that conflicts you,
   in a CVS/SVN style shared workflow, there is no way for you
   to show what you did in isolation.  If you try to follow that
   model in git and insist pushing to the same branch, then you
   are forced to resolve first.

   But you do not have to.  You could push out to another new
   branch, and say "Here is how you could do it, although this
   is based on an older codebase and conflicts with what
   recently happened to the tip".  You could even ask other
   party whose changes conflict with yours to help with the
   merge by saying "I pushed it out, you are more familiar with
   that area of the code and with your changes near the tip of
   the trunk, so could you merge it and push out the result?"

>> Yes, but you get to choose how. Perhaps git-push should list more
>> options than just git-pull, such as the three commands required to
>> rebase the currently checked out branch onto its remote counterpart.
>> That would support more workflows.
>
> I agree. Providing better hints would be good.

I am not so sure about that.  If there are three different
workflows, should git-push give hints suitable for all of them?

The current hint was added in response to users' requests, and I
think it could be generalized.  What we would want the end user
to realize is:

    What I tried to push out is stale, I do not want to push out
    something that does not contain what the other side has
    done, so I need to integrate my work with what the other
    side have before pushing to that branch at the remote.

    In my workflow, that means doing rebase of the branch I
    tried to push out on top of the remote branch I was trying
    to push to.

The second paragraph depends on the workflow.  Do we want to
(can we afford the space to) give a laundry list here?  Probably
not.

>>> Your main objective was to push, but the shared workflow forces
>>> you to do the integration _now_ (by using pull). In a pull-only
>>> workflow, you can just push and defer the integration for later.
>>
>> No, you can also fetch + rebase.
>
> Right. My point was than one cannot defer the integration. It
> must be addressed immediately.

See above.

>>> Some people claim fetch + rebase is superior to fetch + merge.
>>> The only point I can see is that fetch + rebase gives a linear
>>> history without loops, which is nicer to visualize. I recently
>>> asked on the list if there are any benefits of fetch + rebase
>>> over fetch + merge, besides a nicer visualization.
>>
>>
>> It's easier to bisect...
>> With a mostly linear history, this problem goes away.
>
> This is really an interesting point. I did not start to use
> git bisect regularly. But I certainly plan to do so in the future.
>
> Couldn't bisect learn to better cope with non-linear history?

It copes with it as best as it can.

Another thing to think about is how "everybody fetches, merges
and pushes out" would interact with the concept of "mainline".
Strictly speaking, the point of distributed development is that
there is no mainline, but workflows based on "fetch + rebase"
allows --first-parent to give a reasonable approximation of what
people would naively expect how the mainline would look like.
If everybody fetches, merges and pushes out, there is no
"mainline" and --first-parent would give totally useless
history.

^ permalink raw reply

* Re: Newbie: report of first experience with git-rebase.
From: Junio C Hamano @ 2007-11-01 20:20 UTC (permalink / raw)
  To: J. Bruce Fields; +Cc: Johannes Schindelin, Sergei Organov, git
In-Reply-To: <20071101151016.GA26103@fieldses.org>

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

> On Thu, Nov 01, 2007 at 02:24:37PM +0000, Johannes Schindelin wrote:
>> 
>> They are rare events.  In your case I guess that subtly different versions 
>> were _actually_ applied (such as white space fixes),
>
> That's actually pretty common, in my experience.
>
>> which is why such a rare event hit you.
>
> I'm using git to track some changes I submitted to a project that's
> mainly text, and that I only get release tarballs of.  On my most recent
> rebase all my patches got applied, but the text also got re-wrapped and
> re-indented at the same time.  So all but I think one or two of a dozen
> patches ended up with a conflict resolution and then --skip.
>
> Which may not be a case git's really intended for--fair enough.  But
> I've found it's pretty common in my kernel work too.  Either I'm
> rebasing against changes I made myself, or else a maintainer took my
> changes but fixed up some minor style problems along the way.

Ok, so I retract that "rare" comment.

Now, we have established that this is a real problem worth
solving, what's next?

^ permalink raw reply

* Re: What's cooking in git.git (topics)
From: Junio C Hamano @ 2007-11-01 20:27 UTC (permalink / raw)
  To: Geert Bosch; +Cc: Linus Torvalds, git
In-Reply-To: <916BE4AD-5BD9-48E6-8026-B1AC7387E28D@adacore.com>

Geert Bosch <bosch@adacore.com> writes:

> I often type "make clean" as well many "git xyz" commands
> during development, and so it happens that at times, I type
> "git clean" by accident.

Happened to me once.  I hate that command.

> So, I propose *not* converting git clean to a C builtin,
> but instead adding --untracked and --ignored options to
> git-rm.

I think what you are trying to do is to deprecate or remove "git
clean".

I do not know where "git clean" came from.  I am suspecting that
it was to give counterparts to some other SCMs, but do not know
which ones.  Some people wanted to have it --- so you need to
convince them that it is a bad idea first.  Adding an equivalent
options to "git rm" alone does not solve that issue.

^ permalink raw reply

* Re: [PATCH] Implement git commit as a builtin command.
From: Junio C Hamano @ 2007-11-01 20:30 UTC (permalink / raw)
  To: Kristian Høgsberg; +Cc: git
In-Reply-To: <1193944163-22892-1-git-send-email-krh@redhat.com>

Kristian Høgsberg <krh@redhat.com> writes:

> Move git-commit.sh to contrib/examples.
>
> Signed-off-by: Kristian Høgsberg <krh@redhat.com>
> ---
>
> Here's the builtin-commit patch again, this time updated to build
> against the in-tree strbuf and option parser.  Now that Pierre has
> done all the work of getting those pieces upstream, I notice that the
> C version ends up 20 lines shorter than the shell script :)
>
> There's a couple of changes to the test suite at the end, which
> removes some EDITOR=: VISUAL=: hard-coding in a few tests and then
> sets the default editor to /bin/true.  This is to address the problem
> that the C version of launch editor doesn't support any kind of shell
> qouting or built-ins.  Should we just use system(3) here?

I do not care much about _how_ it is done, but one of the most
often typed command in my .history is

	EDITOR=: git commit

I'd be somewhat unhappy to be forced to retrain my fingers ;-)

^ permalink raw reply

* Re: [PATCH] Make git-clone obey "--" (end argument parsing)
From: Junio C Hamano @ 2007-11-01 20:39 UTC (permalink / raw)
  To: Heikki Orsila; +Cc: git
In-Reply-To: <20071101195418.607DA4F95F@jolt.modeemi.cs.tut.fi>

shd@jolt.modeemi.cs.tut.fi (Heikki Orsila) writes:

> Oops. Reposting the patch.
>
> This patch handles "--" argument for git-clone.
>
> Signed-off-by: Heikki Orsila <heikki.orsila@iki.fi>
>
>>From bd2d661c565062eacc80dda90f3978303308f9bb Mon Sep 17 00:00:00 2001
> From: Heikki Orsila <heikki.orsila@iki.fi>
> Date: Thu, 1 Nov 2007 16:21:39 +0200
> Subject: [PATCH] Make git-clone obey "--" (end argument parsing)
>
> ---
>  Documentation/git-clone.txt |    2 +-
>  git-clone.sh                |    5 ++++-
>  2 files changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
> index 253f4f0..7fdcd42 100644
> --- a/Documentation/git-clone.txt
> +++ b/Documentation/git-clone.txt
> @@ -12,7 +12,7 @@ SYNOPSIS
>  'git-clone' [--template=<template_directory>]
>  	  [-l] [-s] [--no-hardlinks] [-q] [-n] [--bare]
>  	  [-o <name>] [-u <upload-pack>] [--reference <repository>]
> -	  [--depth <depth>] <repository> [<directory>]
> +	  [--depth <depth>] [--] <repository> [<directory>]

I do not think this breaks anything, but does it _help_
anything in practice?

What kind of breakage does this patch fix?

^ permalink raw reply

* (unknown), 
From: Francesco Pretto @ 2007-11-01 20:44 UTC (permalink / raw)
  To: git

subscribe git

^ permalink raw reply

* Re:
From: Francesco Pretto @ 2007-11-01 20:48 UTC (permalink / raw)
  To: git
In-Reply-To: <b13782500711011344m4e36bb96jcb17a7981eb5e3b3@mail.gmail.com>

2007/11/1, Francesco Pretto <ceztkoml@gmail.com>:
> subscribe git
>

Sorry! Wrong address trying to subscribe.

^ permalink raw reply

* Re: What's cooking in git.git (topics)
From: Mike Hommey @ 2007-11-01 20:47 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Geert Bosch, Linus Torvalds, git
In-Reply-To: <7v4pg5btis.fsf@gitster.siamese.dyndns.org>

On Thu, Nov 01, 2007 at 01:27:55PM -0700, Junio C Hamano wrote:
> Geert Bosch <bosch@adacore.com> writes:
> 
> > I often type "make clean" as well many "git xyz" commands
> > during development, and so it happens that at times, I type
> > "git clean" by accident.
> 
> Happened to me once.  I hate that command.

Speaking of hateful commands, git stash clear is one of them.
I tend to type git stash clean, which creates a "clean" stash...
 
> > So, I propose *not* converting git clean to a C builtin,
> > but instead adding --untracked and --ignored options to
> > git-rm.
> 
> I think what you are trying to do is to deprecate or remove "git
> clean".
> 
> I do not know where "git clean" came from.  I am suspecting that
> it was to give counterparts to some other SCMs, but do not know
> which ones.  Some people wanted to have it --- so you need to
> convince them that it is a bad idea first.  Adding an equivalent
> options to "git rm" alone does not solve that issue.

Well, they could add an alias, then ;)

Mike

^ permalink raw reply

* Re: What's cooking in git.git (topics)
From: Junio C Hamano @ 2007-11-01 20:57 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git
In-Reply-To: <fgcbjr$3pc$1@ger.gmane.org>

Jakub Narebski <jnareb@gmail.com> writes:

> Junio C Hamano wrote:
>
>> * jc/stash-create (Mon Jul 9 00:51:23 2007 -0700) 2 commits
>>  + rebase: allow starting from a dirty tree.
>>  + stash: implement "stash create"
>> 
>> Will revert at least the latter one, but perhaps both, from
>> 'next'.  The traditional behaviour of refusing to work in a
>> dirty tree is much safer, as the tool cannot decide where to
>> unstash for you.
>
> One of frequently requested features is ability to rebase and merge
> in a dirty tree (CVS-like). Perhaps we should advocate git-stash better,
> e.g. in error message for git-rebase / git-merge / git-pull when in dirty
> state.

I am of two minds about that.  Suggesting to "stash first, do
your thing and unstash" certainly is helpful than not
suggesting.  But wanting to do things in a dirty state, only
because CVS did not allow you to do anything else, is a bad
inertia on the user's side in the first place, and that
helpfulness would actively _encourage_ to keep that bad inertia,
instead of educating the users to think in git-way.

^ permalink raw reply

* [PATCH 0/3] yet more progress display stuff
From: Nicolas Pitre @ 2007-11-01 20:59 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

Here's 3 additional patches.  The first one revert one change already
burried deep in the topic branch based on Shawn's concern about
prune-packed progress display handling.

The second is a generic improvement to the throughput display.

The last is my reimplementation of total transfer byte count, replacing
Shawn's proposed patch which suffered from a few issues.


Nicolas

^ permalink raw reply

* [PATCH 1/3] return the prune-packed progress display to the inner loop
From: Nicolas Pitre @ 2007-11-01 20:59 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <1193950797-29631-1-git-send-email-nico@cam.org>

This reverts commit 0e549137966feb016927a827fb6e359aec8264a3 so to return
to the same state as commit b5d72f0a4cd3cce945ca0d37e4fa0ebbfcdcdb52.

On Wed, 31 Oct 2007, Shawn O. Pearce wrote:
> During my testing with a 40,000 loose object case (yea, I fully
> unpacked a git.git clone I had laying around) my system stalled
> hard in the first object directory.  A *lot* longer than 1 second.
> So I got no progress meter for a long time, and then a progress
> meter appeared on the second directory.

Signed-off-by: Nicolas Pitre <nico@cam.org>
---
 builtin-prune-packed.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/builtin-prune-packed.c b/builtin-prune-packed.c
index f4287da..23faf31 100644
--- a/builtin-prune-packed.c
+++ b/builtin-prune-packed.c
@@ -15,8 +15,6 @@ static void prune_dir(int i, DIR *dir, char *pathname, int len, int opts)
 	struct dirent *de;
 	char hex[40];
 
-	display_progress(progress, i + 1);
-
 	sprintf(hex, "%02x", i);
 	while ((de = readdir(dir)) != NULL) {
 		unsigned char sha1[20];
@@ -32,6 +30,7 @@ static void prune_dir(int i, DIR *dir, char *pathname, int len, int opts)
 			printf("rm -f %s\n", pathname);
 		else if (unlink(pathname) < 0)
 			error("unable to unlink %s", pathname);
+		display_progress(progress, i + 1);
 	}
 	pathname[len] = 0;
 	rmdir(pathname);
-- 
1.5.3.4.279.gb2d9d-dirty

^ permalink raw reply related

* [PATCH 3/3] Show total transferred as part of throughput progress
From: Nicolas Pitre @ 2007-11-01 20:59 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <1193950797-29631-3-git-send-email-nico@cam.org>

Right now it is infeasible to offer to the user a reasonable concept
of when a clone will be complete as we aren't able to come up with
the final pack size until after we have actually transferred the
entire thing to the client.  However in many cases users can work
with a rough rule-of-thumb; for example it is somewhat well known
that git.git is about 16 MiB today and that linux-2.6.git is over
120 MiB.

We now show the total amount of data we have transferred over
the network as part of the throughput meter, organizing it in
"human friendly" terms like `ls -h` would do.  Users can glance at
this, see that the total transferred size is about 3 MiB, see the
throughput of X KiB/sec, and determine a reasonable figure of about
when the clone will be complete, assuming they know the rough size
of the source repository or are able to obtain it.

This is also a helpful indicator that there is progress being made
even if we stall on a very large object.  The thoughput meter may
remain relatively constant and the percentage complete and object
count won't be changing, but the total transferred will be increasing
as additional data is received for this object.

[from an initial proposal from Shawn O. Pearce]

Signed-off-by: Nicolas Pitre <nico@cam.org>
---
 progress.c |   29 ++++++++++++++++++++++++++---
 1 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/progress.c b/progress.c
index 39d5d2c..3f6a602 100644
--- a/progress.c
+++ b/progress.c
@@ -15,13 +15,14 @@
 
 struct throughput {
 	struct timeval prev_tv;
+	off_t total;
 	unsigned long count;
 	unsigned long avg_bytes;
 	unsigned long last_bytes[TP_IDX_MAX];
 	unsigned int avg_misecs;
 	unsigned int last_misecs[TP_IDX_MAX];
 	unsigned int idx;
-	char display[20];
+	char display[32];
 };
 
 struct progress {
@@ -128,6 +129,7 @@ void display_throughput(struct progress *progress, unsigned long n)
 		return;
 	}
 
+	tp->total += n;
 	tp->count += n;
 
 	/*
@@ -149,11 +151,32 @@ void display_throughput(struct progress *progress, unsigned long n)
 	misecs += (int)(tv.tv_usec - tp->prev_tv.tv_usec) / 977;
 
 	if (misecs > 512) {
+		int l = sizeof(tp->display);
 		tp->prev_tv = tv;
 		tp->avg_bytes += tp->count;
 		tp->avg_misecs += misecs;
-		snprintf(tp->display, sizeof(tp->display),
-			 ", %lu KiB/s", tp->avg_bytes / tp->avg_misecs);
+
+		if (tp->total > 1 << 30) {
+			l -= snprintf(tp->display, l, ", %u.%2.2u GiB",
+				      (int)(tp->total >> 30),
+				      (int)(tp->total & ((1 << 30) - 1)) / 10737419);
+		} else if (tp->total > 1 << 20) {
+			l -= snprintf(tp->display, l, ", %u.%2.2u MiB",
+				      (int)(tp->total >> 20),
+				      ((int)(tp->total & ((1 << 20) - 1))
+				       * 100) >> 20);
+		} else if (tp->total > 1 << 10) {
+			l -= snprintf(tp->display, l, ", %u.%2.2u KiB",
+				      (int)(tp->total >> 10),
+				      ((int)(tp->total & ((1 << 10) - 1))
+				       * 100) >> 10);
+		} else {
+			l -= snprintf(tp->display, l, ", %u bytes",
+				      (int)tp->total);
+		}
+		snprintf(tp->display + sizeof(tp->display) - l, l,
+			 " | %lu KiB/s", tp->avg_bytes / tp->avg_misecs);
+
 		tp->avg_bytes -= tp->last_bytes[tp->idx];
 		tp->avg_misecs -= tp->last_misecs[tp->idx];
 		tp->last_bytes[tp->idx] = tp->count;
-- 
1.5.3.4.279.gb2d9d-dirty

^ permalink raw reply related

* [PATCH 2/3] make sure throughput display gets updated even if progress doesn't move
From: Nicolas Pitre @ 2007-11-01 20:59 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <1193950797-29631-2-git-send-email-nico@cam.org>

Currently the progress/throughput display update happens only through
display_progress().  If the progress based on object count remains
unchanged because a large object is being received, the latest throughput
won't be displayed.  The display update should occur through
display_throughput() as well.

Signed-off-by: Nicolas Pitre <nico@cam.org>
---
 progress.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/progress.c b/progress.c
index 34a5961..39d5d2c 100644
--- a/progress.c
+++ b/progress.c
@@ -160,6 +160,9 @@ void display_throughput(struct progress *progress, unsigned long n)
 		tp->last_misecs[tp->idx] = misecs;
 		tp->idx = (tp->idx + 1) % TP_IDX_MAX;
 		tp->count = 0;
+
+		if (progress->last_value != -1 && progress_update)
+			display(progress, progress->last_value, 0);
 	}
 }
 
-- 
1.5.3.4.279.gb2d9d-dirty

^ permalink raw reply related

* [PATCH] Make git-mailinfo strip whitespace from the start of the mail file.
From: Simon Sasburg @ 2007-11-01 21:05 UTC (permalink / raw)
  To: git; +Cc: gitster, Simon Sasburg

This allows you to use files gotten through gmail's web interface via its 'Show original' option.

Signed-off-by: Simon Sasburg <Simon.Sasburg@gmail.com>
---
Note that this doesn't exactly follow RFC 2822 as far as i can see, but i don't know if git prefers to be strict or tolerant in these cases, so i'm sending the patch anyway.

It certaily helps me, even if just a little bit.

 builtin-mailinfo.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
index fb12248..5d4b6bf 100644
--- a/builtin-mailinfo.c
+++ b/builtin-mailinfo.c
@@ -915,6 +915,7 @@ static void handle_info(void)
 static int mailinfo(FILE *in, FILE *out, int ks, const char *encoding,
 		    const char *msg, const char *patch)
 {
+	int peek;
 	keep_subject = ks;
 	metainfo_charset = encoding;
 	fin = in;
@@ -935,6 +936,11 @@ static int mailinfo(FILE *in, FILE *out, int ks, const char *encoding,
 	p_hdr_data = xcalloc(MAX_HDR_PARSED, sizeof(char *));
 	s_hdr_data = xcalloc(MAX_HDR_PARSED, sizeof(char *));
 
+	do {
+		peek = fgetc(in);
+	} while (peek == ' ' || peek == '\r' || peek == '\n');
+	ungetc(peek, in);
+
 	/* process the email header */
 	while (read_one_header_line(line, sizeof(line), fin))
 		check_header(line, sizeof(line), p_hdr_data, 1);
-- 
1.5.3.4.502.g37c97

^ permalink raw reply related

* Re: [PATCH] Don't use cpio in git-clone when not installed
From: Junio C Hamano @ 2007-11-01 21:06 UTC (permalink / raw)
  To: Mike Hommey; +Cc: Nguyen Thai Ngoc Duy, git
In-Reply-To: <20071101105318.GA4744@glandium.org>

Mike Hommey <mh@glandium.org> writes:

> On Wed, Oct 31, 2007 at 06:15:27PM -0700, Junio C Hamano wrote:
>> "Nguyen Thai Ngoc Duy" <pclouds@gmail.com> writes:
>> 
>> > BTW, you have workaround for git-merge also? It uses cpio to save/restore state.
>> 
>> Why do people want "workaround"?  Is installing cpio such a
>> hassle?
>
> Note that to do what git-merge does with cpio, i wonder if it wouldn't
> be sensible to use git stash, now.

Like this?  That's an excellent suggestion.

The patch uses the 'git stash create' which is in 'next'
(jc/stash-create topic).

Having said that, the savestate()/restorestate() codepaths are
only relevant to the "try multiple strategies and pick the best
one" feature of git-merge, and that is where cpio is used (and
the patch rewrites it to use stash).  I am not sure if anybody
ever used it in practice.  I admit I am guilty of inventing it,
but I certainly do not.

It might make sense to remove that try-multiple-strategies
feature from git-merge and be done with it.  It would certainly
make the eventual rewrite to C much easier.

---
 git-merge.sh |   11 +++++------
 1 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/git-merge.sh b/git-merge.sh
index 3a01db0..e8916cc 100755
--- a/git-merge.sh
+++ b/git-merge.sh
@@ -28,20 +28,19 @@ allow_trivial_merge=t
 
 dropsave() {
 	rm -f -- "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/MERGE_MSG" \
-		 "$GIT_DIR/MERGE_SAVE" || exit 1
+		 "$GIT_DIR/MERGE_STASH" || exit 1
 }
 
 savestate() {
 	# Stash away any local modifications.
-	git diff-index -z --name-only $head |
-	cpio -0 -o >"$GIT_DIR/MERGE_SAVE"
+	git stash create >"$GIT_DIR/MERGE_STASH"
 }
 
 restorestate() {
-        if test -f "$GIT_DIR/MERGE_SAVE"
+        if test -f "$GIT_DIR/MERGE_STASH"
 	then
 		git reset --hard $head >/dev/null
-		cpio -iuv <"$GIT_DIR/MERGE_SAVE"
+		git stash apply --index $(cat "$GIT_DIR/MERGE_STASH")
 		git update-index --refresh >/dev/null
 	fi
 }
@@ -386,7 +385,7 @@ case "$use_strategies" in
     single_strategy=no
     ;;
 *)
-    rm -f "$GIT_DIR/MERGE_SAVE"
+    rm -f "$GIT_DIR/MERGE_STASH"
     single_strategy=yes
     ;;
 esac

^ permalink raw reply related

* Re: What's cooking in git.git (topics)
From: Geert Bosch @ 2007-11-01 21:17 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Linus Torvalds, git
In-Reply-To: <7v4pg5btis.fsf@gitster.siamese.dyndns.org>


On Nov 1, 2007, at 16:27, Junio C Hamano wrote:
> Geert Bosch <bosch@adacore.com> writes:
>> I often type "make clean" as well many "git xyz" commands
>> during development, and so it happens that at times, I type
>> "git clean" by accident.
>
> Happened to me once.  I hate that command.
>
>> So, I propose *not* converting git clean to a C builtin,
>> but instead adding --untracked and --ignored options to
>> git-rm.
>
> I think what you are trying to do is to deprecate or remove "git
> clean".

Yes, and in the meantime I'd like to discourage people
from spending time and effort to upgrade it to first
class built-in status.

   -Geert

^ permalink raw reply

* Re: What's cooking in git.git (topics)
From: Theodore Tso @ 2007-11-01 21:18 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Geert Bosch, Linus Torvalds, git
In-Reply-To: <7v4pg5btis.fsf@gitster.siamese.dyndns.org>

On Thu, Nov 01, 2007 at 01:27:55PM -0700, Junio C Hamano wrote:
> I think what you are trying to do is to deprecate or remove "git
> clean".
> 
> I do not know where "git clean" came from.  I am suspecting that
> it was to give counterparts to some other SCMs, but do not know
> which ones.  Some people wanted to have it --- so you need to
> convince them that it is a bad idea first.  Adding an equivalent
> options to "git rm" alone does not solve that issue.

There's this great SCM tool called git that we can use to investigate
the history of changes....  :-)

Looks like it came from Cogito's cg-clean.  No one else has it as far
as I know, and I agree with others that it's a really not such a great
idea.  Fortunately most of the damage can be mitigated with "git
config --global clean.requireForce true", but the newbies won't know
to do that.  

							- Ted

^ permalink raw reply

* Re: What's cooking in git.git (topics)
From: Junio C Hamano @ 2007-11-01 21:20 UTC (permalink / raw)
  To: Mike Hommey; +Cc: Geert Bosch, Linus Torvalds, git
In-Reply-To: <20071101204755.GA15842@glandium.org>

Mike Hommey <mh@glandium.org> writes:

> On Thu, Nov 01, 2007 at 01:27:55PM -0700, Junio C Hamano wrote:
> ...
>> I do not know where "git clean" came from.  I am suspecting that
>> it was to give counterparts to some other SCMs, but do not know
>> which ones.  Some people wanted to have it --- so you need to
>> convince them that it is a bad idea first.  Adding an equivalent
>> options to "git rm" alone does not solve that issue.
>
> Well, they could add an alias, then ;)

Why do people talk about forcing different behaviour on existing
users before proving that the new behaviour is good for
everybody, including existing ones?

I am personally very much in favor of removing "git clean", but
having many people on the list saying loudly that it is a bad
command is not good enough justification, as people who are
content with the status quo tend to be silent.

The steps I think is sensible to transition to that goal would
be:

 - Change clean.requireForce to default to 'true' in the next
   (or one after) version of git, to make 'clean' even safer.
   See if anybody complains (I do not expect any).

 - Implement the same functionarity as a new option to "git rm",
   which is already in C.

 - Do "git clean" in C, but sharing the code with "git rm"
   implementation above.

 - Discuss deprecation and removal of redundant commands.  Ship
   a version of git with deprecation and future removal notice.
   Outline how to achieve the same thing as the deprecated
   command used to do (or give convincing argument why what the
   deprecated command used to do was a bad thing and do not
   offer an alternative).

 - Wait for a while (6 months to 1 year) and then remove them.

^ permalink raw reply

* Re: What's cooking in git.git (topics)
From: Melchior FRANZ @ 2007-11-01 21:26 UTC (permalink / raw)
  To: git
In-Reply-To: <20071101211848.GG2387@thunk.org>

* Theodore Tso -- Thursday 01 November 2007:
> Looks like it came from Cogito's cg-clean.  No one else has it as far
> as I know, [...]

Not built-in. But there are cvs-clean and svn-clean scripts
floating around (and part of KDE), which can be quite useful.
The svn-clean script prompts the user with the number of files
it is about to delete, and asks for confirmation.

m.

^ permalink raw reply

* [RFC PATCH 0/3] Starting rebase from dirty tree
From: Simon Sasburg @ 2007-11-01 21:30 UTC (permalink / raw)
  To: gitster; +Cc: git


These patches allow a --dirty option for git-rebase, git-rebase--interactive, and git-svn rebase.

When --dirty is given, starting from a dirty tree state will be allowed.
The difference between HEAD and the index and between the index and the working tree will be committed,
these commits will be undone when the rebase is completed.

For me the most often used use case is git-svn rebase one, which i use often.
This prevents me form having to commit+reset or stash+unstash everytime i want
to do this in a dirty tree.

I recently saw some discussion about a stash-based patch to do the same thing, and decided to share this.
These patches are a bit rough in some places, and mostly meant to see what others think if this way of doing this.

One advantage above using stash is that merge conflicts will be presented to the user in the same way as when doing a normal rebase.
Also having to explicitly ask for this behaviour with --dirty will hopefully give the user some clue that this isn't a standard operation.

But, in the rebase--interactive case, it allows the user to shoot himself in the foot by re-ordering the commits such that the temporary ones aren't at the end anymore.

Well, comments are welcome :-)

^ permalink raw reply

* [PATCH 1/3] Introduce --dirty option to git-rebase, allowing you to start from a dirty state.
From: Simon Sasburg @ 2007-11-01 21:30 UTC (permalink / raw)
  To: gitster; +Cc: git, Simon Sasburg
In-Reply-To: <1193952624-608-1-git-send-email-Simon.Sasburg@gmail.com>

This will store the difference between HEAD and the index into a commit,
and the difference between the index and the working tree into a commit.

When the rebase is done, it restores the index and the working tree
by undoing these commits with git-reset.

Signed-off-by: Simon Sasburg <Simon.Sasburg@gmail.com>
---
 git-rebase.sh |   63 ++++++++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 54 insertions(+), 9 deletions(-)

diff --git a/git-rebase.sh b/git-rebase.sh
index 224cca9..c923c3b 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -42,6 +42,7 @@ To restore the original branch and stop rebasing run \"git rebase --abort\".
 unset newbase
 strategy=recursive
 do_merge=
+fix_dirty=
 dotest=$GIT_DIR/.dotest-merge
 prec=4
 verbose=
@@ -117,9 +118,39 @@ call_merge () {
 
 finish_rb_merge () {
 	rm -r "$dotest"
+	restore_dirty_state
 	echo "All done."
 }
 
+store_dirty_state () {
+	echo "Storing dirty index/working tree"
+	diff=$(git diff --cached)
+	case "$diff" in
+	?*)	git commit -m "REBASE--dirty: store HEAD..index diff"
+		;;
+	esac
+	diff=$(git diff)
+	case "$diff" in
+	?*)	git commit -a -m "REBASE--dirty: store index..workingtree diff"
+		;;
+	esac
+}
+
+restore_dirty_state () {
+	lastmsg=$(git-rev-list HEAD^..HEAD --pretty=oneline | sed "s:[^ ]* ::")
+	if test "$lastmsg" = "REBASE--dirty: store index..workingtree diff"
+	then
+		echo "Restoring dirty index state"
+		git reset --mixed HEAD^
+	fi
+	lastmsg=$(git-rev-list HEAD^..HEAD --pretty=oneline | sed "s:[^ ]* ::")
+	if test "$lastmsg" = "REBASE--dirty: store HEAD..index diff"
+	then
+		echo "Restoring dirty working dir state"
+		git reset --soft HEAD^
+	fi
+}
+
 is_interactive () {
 	test -f "$dotest"/interactive ||
 	while :; do case $#,"$1" in 0,|*,-i|*,--interactive) break ;; esac
@@ -156,6 +187,10 @@ do
 		git am --resolved --3way --resolvemsg="$RESOLVEMSG"
 		exit
 		;;
+	--dirty)
+		do_merge=t
+		fix_dirty=t
+		;;
 	--skip)
 		if test -d "$dotest"
 		then
@@ -188,6 +223,7 @@ do
 			die "No rebase in progress?"
 		fi
 		git reset --hard ORIG_HEAD
+		restore_dirty_state
 		exit
 		;;
 	--onto)
@@ -253,15 +289,19 @@ else
 	fi
 fi
 
-# The tree must be really really clean.
-git update-index --refresh || exit
-diff=$(git diff-index --cached --name-status -r HEAD)
-case "$diff" in
-?*)	echo "cannot rebase: your index is not up-to-date"
-	echo "$diff"
-	exit 1
-	;;
-esac
+# The tree must be really really clean, unless --dirty is given.
+if test "$fix_dirty" = ""
+then
+	git update-index --refresh || exit
+	diff=$(git diff-index --cached --name-status -r HEAD)
+	case "$diff" in
+	?*)	echo "cannot rebase: your index is not up-to-date"
+		echo "$diff"
+		exit 1
+		;;
+	esac
+	
+fi
 
 # The upstream head must be given.  Make sure it is valid.
 upstream_name="$1"
@@ -318,6 +358,11 @@ then
 	GIT_PAGER='' git diff --stat --summary "$mb" "$onto"
 fi
 
+if test "$fix_dirty" = "t"
+then
+	store_dirty_state
+fi
+
 # Rewind the head to "$onto"; this saves our current head in ORIG_HEAD.
 echo "First, rewinding head to replay your work on top of it..."
 git-reset --hard "$onto"
-- 
1.5.3.4.502.g37c97

^ permalink raw reply related

* [PATCH 2/3] Implement --dirty for git-rebase--interactive.
From: Simon Sasburg @ 2007-11-01 21:30 UTC (permalink / raw)
  To: gitster; +Cc: git, Simon Sasburg
In-Reply-To: <1193952624-608-2-git-send-email-Simon.Sasburg@gmail.com>

Signed-off-by: Simon Sasburg <Simon.Sasburg@gmail.com>
---
 git-rebase--interactive.sh |   42 ++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 76dc679..326076b 100755
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -25,6 +25,7 @@ REWRITTEN="$DOTEST"/rewritten
 PRESERVE_MERGES=
 STRATEGY=
 VERBOSE=
+FIX_DIRTY=
 test -d "$REWRITTEN" && PRESERVE_MERGES=t
 test -f "$DOTEST"/strategy && STRATEGY="$(cat "$DOTEST"/strategy)"
 test -f "$DOTEST"/verbose && VERBOSE=t
@@ -56,6 +57,35 @@ require_clean_work_tree () {
 	die "Working tree is dirty"
 }
 
+store_dirty_state () {
+	echo "Storing dirty index/working tree"
+	diff=$(git diff --cached)
+	case "$diff" in
+	?*)	git commit -m "REBASE--dirty: store HEAD..index diff"
+		;;
+	esac
+	diff=$(git diff)
+	case "$diff" in
+	?*)	git commit -a -m "REBASE--dirty: store index..workingtree diff"
+		;;
+	esac
+}
+
+restore_dirty_state () {
+	lastmsg=$(git-rev-list HEAD^..HEAD --pretty=oneline | sed "s:[^ ]* ::")
+	if test "$lastmsg" = "REBASE--dirty: store index..workingtree diff"
+	then
+		echo "Restoring dirty index state"
+		git reset --mixed HEAD^
+	fi
+	lastmsg=$(git-rev-list HEAD^..HEAD --pretty=oneline | sed "s:[^ ]* ::")
+	if test "$lastmsg" = "REBASE--dirty: store HEAD..index diff"
+	then
+		echo "Restoring dirty working dir state"
+		git reset --soft HEAD^
+	fi
+}
+
 ORIG_REFLOG_ACTION="$GIT_REFLOG_ACTION"
 
 comment_for_reflog () {
@@ -329,6 +359,7 @@ do_next () {
 		test ! -f "$DOTEST"/verbose ||
 			git diff-tree --stat $(cat "$DOTEST"/head)..HEAD
 	} &&
+	restore_dirty_state &&
 	rm -rf "$DOTEST" &&
 	git gc --auto &&
 	warn "Successfully rebased and updated $HEADNAME."
@@ -378,6 +409,7 @@ do
 			;;
 		esac &&
 		output git reset --hard $HEAD &&
+		restore_dirty_state &&
 		rm -rf "$DOTEST"
 		exit
 		;;
@@ -417,6 +449,9 @@ do
 	''|-h)
 		usage
 		;;
+	--dirty)
+		FIX_DIRTY=t
+		;;
 	*)
 		test -d "$DOTEST" &&
 			die "Interactive rebase already started"
@@ -435,7 +470,7 @@ do
 			;;
 		esac
 
-		require_clean_work_tree
+		test "$FIX_DIRTY" = "t" || require_clean_work_tree
 
 		if test ! -z "$2"
 		then
@@ -445,9 +480,12 @@ do
 				die "Could not checkout $2"
 		fi
 
-		HEAD=$(git rev-parse --verify HEAD) || die "No HEAD?"
 		UPSTREAM=$(git rev-parse --verify "$1") || die "Invalid base"
 
+		test "$FIX_DIRTY" = "t" && store_dirty_state
+
+		HEAD=$(git rev-parse --verify HEAD) || die "No HEAD?"
+
 		mkdir "$DOTEST" || die "Could not create temporary $DOTEST"
 
 		test -z "$ONTO" && ONTO=$UPSTREAM
-- 
1.5.3.4.502.g37c97

^ permalink raw reply related

* [PATCH 3/3] Make git-svn rebase --dirty pass along --dirty to git-rebase.
From: Simon Sasburg @ 2007-11-01 21:30 UTC (permalink / raw)
  To: gitster; +Cc: git, Simon Sasburg
In-Reply-To: <1193952624-608-3-git-send-email-Simon.Sasburg@gmail.com>

Signed-off-by: Simon Sasburg <Simon.Sasburg@gmail.com>
---
 git-svn.perl |   16 +++++++++++-----
 1 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/git-svn.perl b/git-svn.perl
index 22bb47b..5898a26 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -63,7 +63,7 @@ my ($_stdin, $_help, $_edit,
 	$_message, $_file,
 	$_template, $_shared,
 	$_version, $_fetch_all, $_no_rebase,
-	$_merge, $_strategy, $_dry_run, $_local,
+	$_merge, $_strategy, $_dry_run, $_local, $_dirty,
 	$_prefix, $_no_checkout, $_verbose);
 $Git::SVN::_follow_parent = 1;
 my %remote_opts = ( 'username=s' => \$Git::SVN::Prompt::_username,
@@ -169,6 +169,7 @@ my %cmd = (
 			  'verbose|v' => \$_verbose,
 			  'strategy|s=s' => \$_strategy,
 			  'local|l' => \$_local,
+			  'dirty|d' => \$_dirty,
 			  'fetch-all|all' => \$_fetch_all,
 			  %fc_opts } ],
 	'commit-diff' => [ \&cmd_commit_diff,
@@ -482,16 +483,20 @@ sub cmd_find_rev {
 }
 
 sub cmd_rebase {
-	command_noisy(qw/update-index --refresh/);
+	unless ($_dirty) {
+		command_noisy(qw/update-index --refresh/);
+	}
 	my ($url, $rev, $uuid, $gs) = working_head_info('HEAD');
 	unless ($gs) {
 		die "Unable to determine upstream SVN information from ",
 		    "working tree history\n";
 	}
 	if (command(qw/diff-index HEAD --/)) {
-		print STDERR "Cannot rebase with uncommited changes:\n";
-		command_noisy('status');
-		exit 1;
+		unless ($_dirty) {
+			print STDERR "Cannot rebase with uncommited changes:\n";
+			command_noisy('status');
+			exit 1;
+		}
 	}
 	unless ($_local) {
 		$_fetch_all ? $gs->fetch_all : $gs->fetch;
@@ -697,6 +702,7 @@ sub rebase_cmd {
 	push @cmd, '-v' if $_verbose;
 	push @cmd, qw/--merge/ if $_merge;
 	push @cmd, "--strategy=$_strategy" if $_strategy;
+	push @cmd, "--dirty" if $_dirty;
 	@cmd;
 }
 
-- 
1.5.3.4.502.g37c97

^ 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