Git development
 help / color / mirror / Atom feed
* [PATCH] builtin-commit: Fix git-commit honoring status.color
From: Ping Yin @ 2007-11-18 17:10 UTC (permalink / raw)
  To: git; +Cc: Ping Yin

status.color shouldn't be honored when committing since the run-status
output is fed to the editor.
---
 builtin-commit.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/builtin-commit.c b/builtin-commit.c
index 8db74ed..4396e7d 100644
--- a/builtin-commit.c
+++ b/builtin-commit.c
@@ -45,6 +45,7 @@ static int quiet, verbose, untracked_files, no_verify;
 static int no_edit, initial_commit, in_merge;
 const char *only_include_assumed;
 struct strbuf message;
+extern int wt_status_use_color;
 
 static int opt_parse_m(const struct option *opt, const char *arg, int unset)
 {
@@ -325,6 +326,7 @@ static int prepare_log_message(const char *index_file, const char *prefix)
 	if (only_include_assumed)
 		fprintf(fp, "# %s\n", only_include_assumed);
 
+	wt_status_use_color = 0;
 	commitable = run_status(fp, index_file, prefix);
 
 	fclose(fp);
-- 
1.5.3.5.1876.g7ba19-dirty

^ permalink raw reply related

* [PATCH 2/2] push: Add '--current', which pushes only the current branch
From: Steffen Prohaska @ 2007-11-18 16:13 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Johannes Schindelin, Steffen Prohaska
In-Reply-To: <11954023881802-git-send-email-prohaska@zib.de>

Often you want to push only the current branch to the default
remote.  This was awkward to do in the past.  You needed to
remember the default remote and type "git push $remote HEAD".

This commit teaches push to do this if you use '--current'.

Signed-off-by: Steffen Prohaska <prohaska@zib.de>
---
 Documentation/git-push.txt |    6 +++++-
 builtin-push.c             |   16 +++++++++++-----
 t/t5516-fetch-push.sh      |   29 +++++++++++++++++++++++++++++
 3 files changed, 45 insertions(+), 6 deletions(-)

diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt
index d2417f3..2dfaf50 100644
--- a/Documentation/git-push.txt
+++ b/Documentation/git-push.txt
@@ -9,7 +9,7 @@ git-push - Update remote refs along with associated objects
 SYNOPSIS
 --------
 [verse]
-'git-push' [--all] [--matching] [--dry-run] [--tags] [--receive-pack=<git-receive-pack>]
+'git-push' [--all] [--matching] [--current] [--dry-run] [--tags] [--receive-pack=<git-receive-pack>]
            [--repo=all] [-f | --force] [-v | --verbose] [<repository> <refspec>...]
 
 DESCRIPTION
@@ -69,6 +69,10 @@ the remote repository.
 	the branch exists locally and at the remote under the same name.
 	Currently, this is the default.  But this will change in the future.
 
+\--current::
+	Instead of naming each ref to push, specifies that only the
+	current branch be pushed.
+
 \--dry-run::
 	Do everything except actually send the updates.
 
diff --git a/builtin-push.c b/builtin-push.c
index 7e9dcf1..e5646d4 100644
--- a/builtin-push.c
+++ b/builtin-push.c
@@ -10,7 +10,7 @@
 #include "parse-options.h"
 
 static const char * const push_usage[] = {
-	"git-push [--all] [--matching] [--dry-run] [--tags] [--receive-pack=<git-receive-pack>] [--repo=all] [-f | --force] [-v] [<repository> <refspec>...]",
+	"git-push [--all] [--matching] [--current] [--dry-run] [--tags] [--receive-pack=<git-receive-pack>] [--repo=all] [-f | --force] [-v] [<repository> <refspec>...]",
 	NULL,
 };
 
@@ -101,6 +101,7 @@ int cmd_push(int argc, const char **argv, const char *prefix)
 	int flags = 0;
 	int all = 0;
 	int matching = 0;
+	int current = 0;
 	int dry_run = 0;
 	int force = 0;
 	int tags = 0;
@@ -111,6 +112,7 @@ int cmd_push(int argc, const char **argv, const char *prefix)
 		OPT_STRING( 0 , "repo", &repo, "repository", "repository"),
 		OPT_BOOLEAN( 0 , "all", &all, "push all refs"),
 		OPT_BOOLEAN( 0 , "matching", &matching, "push matching refs"),
+		OPT_BOOLEAN( 0 , "current", &current, "push current branch"),
 		OPT_BOOLEAN( 0 , "tags", &tags, "push tags"),
 		OPT_BOOLEAN( 0 , "dry-run", &dry_run, "dry run"),
 		OPT_BOOLEAN('f', "force", &force, "force updates"),
@@ -137,15 +139,19 @@ int cmd_push(int argc, const char **argv, const char *prefix)
 		repo = argv[0];
 		set_refspecs(argv + 1, argc - 1);
 	}
-	if ((all != 0) + (matching != 0) > 1) {
-		fprintf(stderr, "--all and --matching are mutual exclusive.\n");
+	if ((all != 0) + (matching != 0) + (current != 0) > 1) {
+		fprintf(stderr, "--all, --matching, and --current are mutual exclusive.\n");
 		usage_with_options(push_usage, options);
 	}
-	if ((all || matching) && refspec)
+	if ((all || matching || current) && refspec)
 		usage_with_options(push_usage, options);
-	if (!all && !matching && !refspec)
+	if (!all && !matching && !current && !refspec)
 		fprintf(stderr, "Warning: assuming '--matching'."
 		                " This default will change in the future.\n");
+	if (current) {
+		const char* head[1] = { "HEAD" };
+		set_refspecs(head, 1);
+	}
 
 	return do_push(repo, flags);
 }
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index 21aa7c3..20e0796 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -113,6 +113,18 @@ test_expect_success 'push command line options (3)' '
 	grep -q "Warning: assuming.*--matching" stderr.txt
 '
 
+test_expect_code 129 'push command line options (4)' '
+	git push --all --current testrepo
+'
+
+test_expect_code 129 'push command line options (5)' '
+	git push --matching --current testrepo
+'
+
+test_expect_code 129 'push command line options (6)' '
+	git push --current testrepo master
+'
+
 test_expect_success 'push without wildcard' '
 	mk_empty &&
 
@@ -284,6 +296,23 @@ test_expect_success 'push with HEAD nonexisting at remote' '
 	check_push_result $the_commit heads/local
 '
 
+test_expect_success 'push with --current' '
+
+	mk_test heads/master &&
+	git checkout master &&
+	git push --current testrepo &&
+	check_push_result $the_commit heads/master
+
+'
+
+test_expect_success 'push with --current nonexisting at remote' '
+
+	mk_test heads/master &&
+	git checkout local &&
+	git push --current testrepo &&
+	check_push_result $the_commit heads/local
+'
+
 test_expect_success 'push with dry-run' '
 
 	mk_test heads/master &&
-- 
1.5.3.5.743.g87c5c

^ permalink raw reply related

* [PATCH 1/2] push: Add '--matching' option and print warning if it should be used
From: Steffen Prohaska @ 2007-11-18 16:13 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Johannes Schindelin, Steffen Prohaska
In-Reply-To: <Pine.LNX.4.64.0711121501500.4362@racer.site>

This on the road to
1) "git push --matching" pushes matching branches.
2) "git push --current" pushes only current branch.
3) "git push" reports error if the config does not contain a Push line.
   (after it reported a warning for a while).

Maybe in two years (that's twice an eternity in git time scales):

4) make "git push --current" the default.

This commit adds '--matching', which is a no-op at this point.
If appropriate, a warning is printed to tell the user that the
default will change in the future.

Thanks to Dscho for suggesting this.

Signed-off-by: Steffen Prohaska <prohaska@zib.de>
---
 Documentation/git-push.txt |    8 +++++++-
 builtin-push.c             |   13 +++++++++++--
 t/t5516-fetch-push.sh      |   13 +++++++++++++
 3 files changed, 31 insertions(+), 3 deletions(-)

So here is '--matching'. And PATCH 2/2 will bring '--current'.
They apply on top of sp/refspec-match.

    Steffen

diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt
index 4a68aab..d2417f3 100644
--- a/Documentation/git-push.txt
+++ b/Documentation/git-push.txt
@@ -9,7 +9,7 @@ git-push - Update remote refs along with associated objects
 SYNOPSIS
 --------
 [verse]
-'git-push' [--all] [--dry-run] [--tags] [--receive-pack=<git-receive-pack>]
+'git-push' [--all] [--matching] [--dry-run] [--tags] [--receive-pack=<git-receive-pack>]
            [--repo=all] [-f | --force] [-v | --verbose] [<repository> <refspec>...]
 
 DESCRIPTION
@@ -63,6 +63,12 @@ the remote repository.
 	Instead of naming each ref to push, specifies that all
 	refs under `$GIT_DIR/refs/heads/` be pushed.
 
+\--matching::
+	Instead of naming each ref to push, specifies that matching
+	refs under `$GIT_DIR/refs/heads/` be pushed.  Matching means
+	the branch exists locally and at the remote under the same name.
+	Currently, this is the default.  But this will change in the future.
+
 \--dry-run::
 	Do everything except actually send the updates.
 
diff --git a/builtin-push.c b/builtin-push.c
index 54fba0e..7e9dcf1 100644
--- a/builtin-push.c
+++ b/builtin-push.c
@@ -10,7 +10,7 @@
 #include "parse-options.h"
 
 static const char * const push_usage[] = {
-	"git-push [--all] [--dry-run] [--tags] [--receive-pack=<git-receive-pack>] [--repo=all] [-f | --force] [-v] [<repository> <refspec>...]",
+	"git-push [--all] [--matching] [--dry-run] [--tags] [--receive-pack=<git-receive-pack>] [--repo=all] [-f | --force] [-v] [<repository> <refspec>...]",
 	NULL,
 };
 
@@ -100,6 +100,7 @@ int cmd_push(int argc, const char **argv, const char *prefix)
 {
 	int flags = 0;
 	int all = 0;
+	int matching = 0;
 	int dry_run = 0;
 	int force = 0;
 	int tags = 0;
@@ -109,6 +110,7 @@ int cmd_push(int argc, const char **argv, const char *prefix)
 		OPT__VERBOSE(&verbose),
 		OPT_STRING( 0 , "repo", &repo, "repository", "repository"),
 		OPT_BOOLEAN( 0 , "all", &all, "push all refs"),
+		OPT_BOOLEAN( 0 , "matching", &matching, "push matching refs"),
 		OPT_BOOLEAN( 0 , "tags", &tags, "push tags"),
 		OPT_BOOLEAN( 0 , "dry-run", &dry_run, "dry run"),
 		OPT_BOOLEAN('f', "force", &force, "force updates"),
@@ -135,8 +137,15 @@ int cmd_push(int argc, const char **argv, const char *prefix)
 		repo = argv[0];
 		set_refspecs(argv + 1, argc - 1);
 	}
-	if ((flags & TRANSPORT_PUSH_ALL) && refspec)
+	if ((all != 0) + (matching != 0) > 1) {
+		fprintf(stderr, "--all and --matching are mutual exclusive.\n");
 		usage_with_options(push_usage, options);
+	}
+	if ((all || matching) && refspec)
+		usage_with_options(push_usage, options);
+	if (!all && !matching && !refspec)
+		fprintf(stderr, "Warning: assuming '--matching'."
+		                " This default will change in the future.\n");
 
 	return do_push(repo, flags);
 }
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index fd5f284..21aa7c3 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -100,6 +100,19 @@ test_expect_success 'fetch with wildcard' '
 	)
 '
 
+test_expect_code 129 'push command line options (1)' '
+	git push --all --matching testrepo
+'
+
+test_expect_code 129 'push command line options (2)' '
+	git push --matching testrepo master
+'
+
+test_expect_success 'push command line options (3)' '
+	git push testrepo 2>stderr.txt &&
+	grep -q "Warning: assuming.*--matching" stderr.txt
+'
+
 test_expect_success 'push without wildcard' '
 	mk_empty &&
 
-- 
1.5.3.5.743.g87c5c

^ permalink raw reply related

* [PATCH] Bisect: use "$GIT_DIR/BISECT_NAMES" to check if we are bisecting.
From: Christian Couder @ 2007-11-18 15:34 UTC (permalink / raw)
  To: Junio Hamano; +Cc: git

Previously we tested if the "$GIT_DIR/refs/bisect" directory
existed, to check if we were bisecting.

Now with packed refs, it is simpler to check if the file
"$GIT_DIR/BISECT_NAMES" exists, as it is already created when
starting bisection and removed when reseting bisection.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
 git-bisect.sh |    7 ++-----
 1 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/git-bisect.sh b/git-bisect.sh
index 4748c6a..01593eb 100755
--- a/git-bisect.sh
+++ b/git-bisect.sh
@@ -37,7 +37,7 @@ sq() {
 }
 
 bisect_autostart() {
-	test -d "$GIT_DIR/refs/bisect" || {
+	test -f "$GIT_DIR/BISECT_NAMES" || {
 		echo >&2 'You need to start by "git bisect start"'
 		if test -t 0
 		then
@@ -83,7 +83,6 @@ bisect_start() {
 	# Get rid of any old bisect state
 	#
 	bisect_clean_state
-	mkdir "$GIT_DIR/refs/bisect"
 
 	#
 	# Check for one bad and then some good revisions.
@@ -192,7 +191,7 @@ bisect_next_check() {
 		;;
 	*)
 		THEN=''
-		test -d "$GIT_DIR/refs/bisect" || {
+		test -f "$GIT_DIR/BISECT_NAMES" || {
 			echo >&2 'You need to start by "git bisect start".'
 			THEN='then '
 		}
@@ -349,8 +348,6 @@ bisect_reset() {
 }
 
 bisect_clean_state() {
-	rm -fr "$GIT_DIR/refs/bisect"
-
 	# There may be some refs packed during bisection.
 	git for-each-ref --format='%(refname) %(objectname)' refs/bisect/\* refs/heads/bisect |
 	while read ref hash
-- 
1.5.3.5.1815.g9445b-dirty

^ permalink raw reply related

* ! [rejected] master -> master (non-fast forward)
From: Jon Smirl @ 2007-11-18 15:12 UTC (permalink / raw)
  To: Git Mailing List

What's causing this? I'm using stgit on the master branch.
I'm fixing it each time on the remote server by deleting the ref to master.

jonsmirl@terra:~/ds$ git push digispeaker
To ssh://jonsmirl1@git.digispeaker.com/~/projects/digispeaker-kernel.git
 ! [rejected]        master -> master (non-fast forward)
error: failed to push to
'ssh://jonsmirl1@git.digispeaker.com/~/projects/digispeaker-kernel.git'
jonsmirl@terra:~/ds$

On the server I have:
[core]
        repositoryformatversion = 0
        filemode = true
        bare = true
        logallrefupdates = true

bare was set false, I just flipped it to true. The server repo was
originally created via a clone from kernel.org and then renamed to be
a bare repo. Why do we need a 'bare' attribute?

-- 
Jon Smirl
jonsmirl@gmail.com

^ permalink raw reply

* only accessing some git repos: Am I configuring daemon wrong?
From: Henrik Vendelbo @ 2007-11-18 13:18 UTC (permalink / raw)
  To: git

I run the daemon against a base directory with all my repos.

/repositories
  + /blingon
     + /config
  + /thepia
     + /config

The config directories are git repositories, and the repos are made
available with the following command:

henrik-computer:~ x$ git daemon --export-all --verbose --base-path=/repositories
[337] Connection from 192.168.9.130:56583
[337] Extended attributes (20 bytes) exist <host=192.168.9.165>
[337] Request upload-pack for '/blingon/all'
[337] Disconnected

For some reason when I try to pull over the git protocol to a
different machine using clone, I get a failure telling me that there
is 'no matching remote head'

I tried specifying the actual repo directories, but that made no difference.

Any ideas?

Henrik

^ permalink raw reply

* Re: [PATCH] fetch-pack: Prepare for a side-band demultiplexer in a thread.
From: Johannes Sixt @ 2007-11-18 12:23 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano
In-Reply-To: <7v3av3yi1x.fsf@gitster.siamese.dyndns.org>

On Sunday 18 November 2007 11:16, Junio C Hamano wrote:
> Johannes Sixt <johannes.sixt@telecom.at> writes:
> >> If the rationale was "running in a thread is more natural on the
> >> platform", I would understand it.
> >
> > Please take it as such.
> >
> >> But "_must_ run because there is no fork(2)" solicits a "Huh?
> >> How does Cygwin does it then?" from me.
> >
> > Alex has answered this. We are not going to copy Cygwin's fork() into
> > git.
>
> Wholeheartedly agree, and I feel dirty after looking at that
> thing.  Nothing against Cygwin folks, of course.
>
> The reason I wanted to close pipes as early as possible was
> because I did not want to get bitten by "read() waiting forever
> for EOF due to an extra unclosed fd on the writer end of the
> pipe() without the writer not writing anything to it" problem,
> which is an often-seen mistake.

That was my concern, too, and I spent quite a few brain cycles to verify that 
this is not the case here.

-- Hannes

^ permalink raw reply

* Re: [RFH] Solaris portability
From: Guido Ostkamp @ 2007-11-18 12:08 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Guido Ostkamp, git, Shawn O Pearce, Jason Riedy, Dennis Stosberg
In-Reply-To: <7vtznlww0t.fsf_-_@gitster.siamese.dyndns.org>

On Fri, 16 Nov 2007, Junio C Hamano wrote:
> This makes me wonder if treating it just like strcasestr() might be 
> simpler.  Could folks with access to Solaris boxes of different vintages 
> please see if the attached patch makes sense?

I think the patch makes sense as neither Solaris 8, 9 nor 10 supports 
mkdtemp().

> Can we also unify UNSETENV, SETENV, C99_FORMAT and STRTOUMAX, by the 
> way?

No.

I've just checked on our Solaris Sparc systems, and found that the 
C-library provides unsetenv(), setenv() and strtoumax() beginning with 
Solaris 10; also the 'man sprintf' page mentions the 'z' and 't' 
specifiers for printf (which is what is behind C99_FORMAT) only beginning 
with Solaris 10.

So workarounds are needed for all 4 cases for Solaris 8 and 9 but not 10.

Regards

Guido

^ permalink raw reply

* [RFC] Alternates and broken repos: A pack and prune scheme to avoid them
From: Johannes Sixt @ 2007-11-18 11:25 UTC (permalink / raw)
  To: git

As you know, repo.or.cz uses alternates in order to reduce the space that the 
repositories of forked projects require.

Recently, it happened that a fork (4msysgit.git) became broken because it was 
using an object that was pruned away from the repository that it was 
borrowing from (mingw.git). This happened even though 4msysgit did not use 
the branch of mingw.git that was rebased and whose objects were pruned. The 
reason is that a merge in 4msysgit.git resulted in a blob that was also in 
the rebased branch.

To avoid such situations I propose to introduce "attic" packs. They contain 
objects that are unreachable by the local set of refs. Otherwise they are 
used like regular packs.

git-repack produces "attic" packs like this:

- Places objects of the local object store that are unreachable in an "attic" 
pack.
- Copies objects that are reachable but borrowed from an alternate and are 
only in the alternates' "attic" packs into the local regular pack.

git-prune removes "attic" packs.

Then the strategy of garbage collection can be arranged in the following way:

- Repack by starting at the "most complete" repo and work towards the "most 
borrowing" ones. During this phase "attic" packs are created. Borrowing repos 
get a chance to salvage objects before the alternates prune them away.

- Prune by starting at the "most borrowing" repo and work towards the "most 
complete" ones. During this phase the "attic" packs are cleaned up.

What do you think? Is this a way for a solution?

-- Hannes

^ permalink raw reply

* Re: [PATCH] fetch-pack: Prepare for a side-band demultiplexer in a thread.
From: Robin Rosenberg @ 2007-11-18 11:03 UTC (permalink / raw)
  To: Johannes Sixt; +Cc: Junio C Hamano, git
In-Reply-To: <200711172309.28364.johannes.sixt@telecom.at>

lördag 17 november 2007 skrev Johannes Sixt:
> Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
> ---
> 	This change again originates from the MinGW port. Since we don't
> 	have fork(2) on Windows, we must run the sideband demultiplexer
> 	in a thread.

I think this explanation deserves a place in the commit too.

-- robin

^ permalink raw reply

* Re: [PATCH] builtin-commit: fix partial-commit support
From: Junio C Hamano @ 2007-11-18 10:57 UTC (permalink / raw)
  To: git
In-Reply-To: <1195381287-26823-4-git-send-email-gitster@pobox.com>

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

> ...
> Additionally:

   - read the index file after pre-commit hook returns, as the
     hook can modify it to affect the contents of the commit.

>  - remove the temporary index file .git/next-index-* after
>    commit is done or aborted.
>
>  - run post-commit hook with the real index file to be used
>    after the commit (previously it gave the temporary commit if
>    a partial commit was made).
>
>  - resurrect the safety mechanism to refuse partial commits
>    during a merge to match the scripted version.

>  static char *prepare_index(const char **files, const char *prefix)
>  {
>  	int fd;
>  	struct tree *tree;
> -	struct lock_file *next_index_lock;
> +	struct path_list partial;
> +	const char **pathspec = NULL;
>  
>  	if (interactive) {
>  		interactive_add();
> +		commit_style = COMMIT_NORMAL;

This should be COMMIT_AS_IS, to match the scripted version.

> +	/*
> +	 * A partial commit.
> +	 *
> +	 * (0) find the set of affected paths [NEEDSWORK]

This [NEEDSWORK] has been resolved.

> +	 * (1) get lock on the real index file;
> +	 * (2) update the_index with the given paths;
> +	 * (3) write the_index out to the real index (still locked);
> +	 * (4) get lock on the false index file;
> +	 * (5) reset the_index from HEAD, but keep the addition;

This ", but keep the addition" is no longer necessary; the set
of paths discovered in step (0) _will_ include the added paths
that are named by the user in **files.

> +	 * (6) update the_index the same way as (2);
> +	 * (7) write the_index out to the false index file;
> +	 * (8) return the name of the false index file (still locked);
> +	 *
> +	 * The caller should run hooks on the locked false index, and

 ... "create the commit using the false index", of course.

> +	 * (A) if all goes well, commit the real index;
> +	 * (B) on failure, rollback the real index;
> +	 * In either case, rollback the false index.
> +	 */

^ permalink raw reply

* Re: preserving mtime
From: Robin Rosenberg @ 2007-11-18 10:42 UTC (permalink / raw)
  To: Jan Hudec; +Cc: Mike Hommey, Wayne Davison, Andreas Ericsson, git
In-Reply-To: <20071118094038.GA11861@efreet.light.src>


There's an FAQ on this topic on the wiki as it pops up every now and then.

-- robin

^ permalink raw reply

* Re: Git User's Survey 2007 summary at GitWiki
From: Jakub Narebski @ 2007-11-18 10:39 UTC (permalink / raw)
  To: Robin Rosenberg; +Cc: git
In-Reply-To: <200711181127.09385.robin.rosenberg.lists@dewire.com>

On Sun, Nov 18, 2007, Robin Rosenberg wrote:
> fredag 16 november 2007 skrev Jakub Narebski:

>> I'd like to announce that summary of Git User's Survey 2007 is now 
>> present on Git Wiki at
>> 
>>   http://git.or.cz/gitwiki/GitSurvey2007
>> 
>> 
>> P.S. There are still few questions for which there are not full 
>> analysis, or are not analized at all.
> 
> Comments to some comments:
>
>> I wonder what are those 15 other GUI. Why oh why there were no
>> "What is this 'other GUI'?" question... 
> 
> I know I checked "other", which in my case meant The Eclipse Plugin.

The Eclipse Plugin was removed from the GUI list on request from someone 
at git mailing list during an RFC phase for survey questions. Egit is
neither fish nor fowl: it looks like GUI, but it is more than just
a porcelain; it is implementation of git in Java.

I think I should have put it among porcelains 
  "26. Which porcelains do you use?"


I definitely should have added 'what other' for each single chioce / 
multiple choice question where 'other' was one of possible answers. 
Ehh...

-- 
Jakub Narebski
Poland

^ permalink raw reply

* Re: [PATCH] builtin-commit: fix partial-commit support
From: Junio C Hamano @ 2007-11-18 10:26 UTC (permalink / raw)
  To: git
In-Reply-To: <1195381287-26823-4-git-send-email-gitster@pobox.com>

The above four are to be applied on top of kh/commit series,
(without the WIP I sent out last night) on top of Dscho's
"Replace "runstatus" with "status" in the tests" patch.

With these, all tests in t/ finally passes for me ;-)

But I am not a heavy user of partial commits nor commits from
subdirectories, so there may still be breakages.

^ permalink raw reply

* Re: Git User's Survey 2007 summary at GitWiki
From: Robin Rosenberg @ 2007-11-18 10:27 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git
In-Reply-To: <200711160302.59786.jnareb@gmail.com>

fredag 16 november 2007 skrev Jakub Narebski:
> I'd like to announce that summary of Git User's Survey 2007 is now 
> present on Git Wiki at
> 
>   http://git.or.cz/gitwiki/GitSurvey2007
> 
> 
> P.S. There are still few questions for which there are not full 
> analysis, or are not analized at all.

Comments to some comments:
>I wonder what are those 15 other GUI. Why oh why there were no "What is this 'other GUI'?" question...

I know I checked "other", which in my case meant The Eclipse Plugin.

-- robin

^ permalink raw reply

* [PATCH] builtin-commit: fix partial-commit support
From: Junio C Hamano @ 2007-11-18 10:21 UTC (permalink / raw)
  To: git
In-Reply-To: <1195381287-26823-3-git-send-email-gitster@pobox.com>

When making a partial-commit, we need to prepare two index
files, one to be used to write out the tree to be committed
(temporary index) and the other to be used as the index file
after the commit is made.

The temporary index needs to be initialized to HEAD and then all
the named paths on the command line need to be staged on top of
the index.  For this, running add_files_to_cache() that compares
what is in the index and the paths given from the command line
is not enough -- the comparison will miss the paths that the
user previously ran "git add" to the index since the HEAD
because the index reset to the HEAD would not know about them.
The index file needs to get the same modification done when
preparing the temporary index as described above.

This implementation mimics the behaviour of the scripted
version of git-commit.  It first runs overlay_tree_on_cache(),
which was stolen from ls-files with the earlier change, to get
the list of paths that the user can potentially mean, and then
uses pathspec_match() to find which ones the user meant.  This
list of paths is used to update both the temporary and the real
index file.

Additionally:

 - remove the temporary index file .git/next-index-* after
   commit is done or aborted.

 - run post-commit hook with the real index file to be used
   after the commit (previously it gave the temporary commit if
   a partial commit was made).

 - resurrect the safety mechanism to refuse partial commits
   during a merge to match the scripted version.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin-commit.c |  245 +++++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 205 insertions(+), 40 deletions(-)

diff --git a/builtin-commit.c b/builtin-commit.c
index 3e7d281..e487bc0 100644
--- a/builtin-commit.c
+++ b/builtin-commit.c
@@ -7,6 +7,7 @@
 
 #include "cache.h"
 #include "cache-tree.h"
+#include "dir.h"
 #include "builtin.h"
 #include "diff.h"
 #include "diffcore.h"
@@ -19,6 +20,7 @@
 #include "strbuf.h"
 #include "utf8.h"
 #include "parse-options.h"
+#include "path-list.h"
 
 static const char * const builtin_commit_usage[] = {
 	"git-commit [options] [--] <filepattern>...",
@@ -28,7 +30,13 @@ static const char * const builtin_commit_usage[] = {
 static unsigned char head_sha1[20], merge_head_sha1[20];
 static char *use_message_buffer;
 static const char commit_editmsg[] = "COMMIT_EDITMSG";
-static struct lock_file lock_file;
+static struct lock_file index_lock; /* real index */
+static struct lock_file false_lock; /* used only for partial commits */
+static enum {
+	COMMIT_AS_IS = 1,
+	COMMIT_NORMAL,
+	COMMIT_PARTIAL,
+} commit_style;
 
 static char *logfile, *force_author, *template_file;
 static char *edit_message, *use_message;
@@ -78,41 +86,182 @@ static struct option builtin_commit_options[] = {
 	OPT_END()
 };
 
+static void rollback_index_files(void)
+{
+	switch (commit_style) {
+	case COMMIT_AS_IS:
+		break; /* nothing to do */
+	case COMMIT_NORMAL:
+		rollback_lock_file(&index_lock);
+		break;
+	case COMMIT_PARTIAL:
+		rollback_lock_file(&index_lock);
+		rollback_lock_file(&false_lock);
+		break;
+	}
+}
+
+static void commit_index_files(void)
+{
+	switch (commit_style) {
+	case COMMIT_AS_IS:
+		break; /* nothing to do */
+	case COMMIT_NORMAL:
+		commit_lock_file(&index_lock);
+		break;
+	case COMMIT_PARTIAL:
+		commit_lock_file(&index_lock);
+		rollback_lock_file(&false_lock);
+		break;
+	}
+}
+
+/*
+ * Take a union of paths in the index and the named tree (typically, "HEAD"),
+ * and return the paths that match the given pattern in list.
+ */
+static int list_paths(struct path_list *list, const char *with_tree,
+		      const char *prefix, const char **pattern)
+{
+	struct dir_struct dir;
+	int i;
+	char *m;
+
+	for (i = 0; pattern[i]; i++)
+		;
+	m = xcalloc(1, i);
+
+	memset(&dir, 0, sizeof(dir));
+	if (with_tree)
+		overlay_tree_on_cache(with_tree, prefix);
+
+	for (i = 0; i < active_nr; i++) {
+		struct cache_entry *ce = active_cache[i];
+		if (ce->ce_flags & htons(CE_UPDATE))
+			continue;
+		if (!pathspec_match(pattern, m, ce->name, 0))
+			continue;
+		if (excluded(&dir, ce->name))
+			continue;
+		path_list_insert(ce->name, list);
+	}
+
+	return report_path_error(m, pattern, prefix ? strlen(prefix) : 0);
+}
+
+static void add_remove_files(struct path_list *list)
+{
+	int i;
+	for (i = 0; i < list->nr; i++) {
+		struct path_list_item *p = &(list->items[i]);
+		if (file_exists(p->path))
+			add_file_to_cache(p->path, 0);
+		else
+			remove_file_from_cache(p->path);
+	}
+}
+
 static char *prepare_index(const char **files, const char *prefix)
 {
 	int fd;
 	struct tree *tree;
-	struct lock_file *next_index_lock;
+	struct path_list partial;
+	const char **pathspec = NULL;
 
 	if (interactive) {
 		interactive_add();
+		commit_style = COMMIT_NORMAL;
 		return get_index_file();
 	}
 
-	fd = hold_locked_index(&lock_file, 1);
 	if (read_cache() < 0)
 		die("index file corrupt");
 
-	if (all || also) {
-		add_files_to_cache(verbose, also ? prefix : NULL, files);
+	if (*files)
+		pathspec = get_pathspec(prefix, files);
+
+	/*
+	 * Non partial, non as-is commit.
+	 *
+	 * (1) get the real index;
+	 * (2) update the_index as necessary;
+	 * (3) write the_index out to the real index (still locked);
+	 * (4) return the name of the locked index file.
+	 *
+	 * The caller should run hooks on the locked real index, and
+	 * (A) if all goes well, commit the real index;
+	 * (B) on failure, rollback the real index.
+	 */
+	if (all || (also && pathspec && *pathspec)) {
+		int fd = hold_locked_index(&index_lock, 1);
+		add_files_to_cache(0, also ? prefix : NULL, pathspec);
 		refresh_cache(REFRESH_QUIET);
 		if (write_cache(fd, active_cache, active_nr) || close(fd))
 			die("unable to write new_index file");
-		return lock_file.filename;
+		commit_style = COMMIT_NORMAL;
+		return index_lock.filename;
 	}
 
-	if (*files == NULL) {
-		/* Commit index as-is. */
-		rollback_lock_file(&lock_file);
+	/*
+	 * As-is commit.
+	 *
+	 * (1) return the name of the real index file.
+	 *
+	 * The caller should run hooks on the real index, and run
+	 * hooks on the real index, and create commit from the_index.
+	 * We still need to refresh the index here.
+	 */
+	if (!pathspec || !*pathspec) {
+		fd = hold_locked_index(&index_lock, 1);
+		refresh_cache(REFRESH_QUIET);
+		if (write_cache(fd, active_cache, active_nr) ||
+		    close(fd) || commit_locked_index(&index_lock))
+			die("unable to write new_index file");
+		commit_style = COMMIT_AS_IS;
 		return get_index_file();
 	}
 
-	/* update the user index file */
-	add_files_to_cache(verbose, prefix, files);
+	/*
+	 * A partial commit.
+	 *
+	 * (0) find the set of affected paths [NEEDSWORK]
+	 * (1) get lock on the real index file;
+	 * (2) update the_index with the given paths;
+	 * (3) write the_index out to the real index (still locked);
+	 * (4) get lock on the false index file;
+	 * (5) reset the_index from HEAD, but keep the addition;
+	 * (6) update the_index the same way as (2);
+	 * (7) write the_index out to the false index file;
+	 * (8) return the name of the false index file (still locked);
+	 *
+	 * The caller should run hooks on the locked false index, and
+	 * (A) if all goes well, commit the real index;
+	 * (B) on failure, rollback the real index;
+	 * In either case, rollback the false index.
+	 */
+	commit_style = COMMIT_PARTIAL;
+
+	if (file_exists(git_path("MERGE_HEAD")))
+		die("cannot do a partial commit during a merge.");
+
+	memset(&partial, 0, sizeof(partial));
+	partial.strdup_paths = 1;
+	if (list_paths(&partial, initial_commit ? NULL : "HEAD", prefix, pathspec))
+		exit(1);
+
+	discard_cache();
+	if (read_cache() < 0)
+		die("cannot read the index");
+
+	fd = hold_locked_index(&index_lock, 1);
+	add_remove_files(&partial);
 	refresh_cache(REFRESH_QUIET);
 	if (write_cache(fd, active_cache, active_nr) || close(fd))
 		die("unable to write new_index file");
 
+	fd = hold_lock_file_for_update(&false_lock,
+				       git_path("next-index-%d", getpid()), 1);
+	discard_cache();
 	if (!initial_commit) {
 		tree = parse_tree_indirect(head_sha1);
 		if (!tree)
@@ -120,17 +269,12 @@ static char *prepare_index(const char **files, const char *prefix)
 		if (read_tree(tree, 0, NULL))
 			die("failed to read HEAD tree object");
 	}
-
-	/* Use a lock file to garbage collect the temporary index file. */
-	next_index_lock = xmalloc(sizeof(*next_index_lock));
-	fd = hold_lock_file_for_update(next_index_lock,
-				       git_path("next-index-%d", getpid()), 1);
-	add_files_to_cache(verbose, prefix, files);
+	add_remove_files(&partial);
 	refresh_cache(REFRESH_QUIET);
-	if (write_cache(fd, active_cache, active_nr) || close(fd))
-		die("unable to write new_index file");
 
-	return next_index_lock->filename;
+	if (write_cache(fd, active_cache, active_nr) || close(fd))
+		die("unable to write temporary index file");
+	return false_lock.filename;
 }
 
 static int run_status(FILE *fp, const char *index_file, const char *prefix)
@@ -437,7 +581,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)
 
 	commitable = run_status(stdout, index_file, prefix);
 
-	rollback_lock_file(&lock_file);
+	rollback_index_files();
 
 	return commitable ? 0 : 1;
 }
@@ -527,23 +671,36 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
 
 	index_file = prepare_index(argv, prefix);
 
-	if (!no_verify && run_hook(index_file, "pre-commit", NULL))
-		exit(1);
+	if (!no_verify && run_hook(index_file, "pre-commit", NULL)) {
+		rollback_index_files();
+		return 1;
+	}
 
 	if (!prepare_log_message(index_file, prefix) && !in_merge) {
 		run_status(stdout, index_file, prefix);
+		rollback_index_files();
 		unlink(commit_editmsg);
 		return 1;
 	}
 
-	strbuf_init(&sb, 0);
-
-	/* Start building up the commit header */
+	/*
+	 * Re-read the index as pre-commit hook could have updated it,
+	 * and write it out as a tree.
+	 */
+	discard_cache();
 	read_cache_from(index_file);
-	active_cache_tree = cache_tree();
+	if (!active_cache_tree)
+		active_cache_tree = cache_tree();
 	if (cache_tree_update(active_cache_tree,
-			      active_cache, active_nr, 0, 0) < 0)
+			      active_cache, active_nr, 0, 0) < 0) {
+		rollback_index_files();
 		die("Error building trees");
+	}
+
+	/*
+	 * The commit object
+	 */
+	strbuf_init(&sb, 0);
 	strbuf_addf(&sb, "tree %s\n",
 		    sha1_to_hex(active_cache_tree->sha1));
 
@@ -592,20 +749,27 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
 	header_len = sb.len;
 	if (!no_edit)
 		launch_editor(git_path(commit_editmsg), &sb);
-	else if (strbuf_read_file(&sb, git_path(commit_editmsg), 0) < 0)
+	else if (strbuf_read_file(&sb, git_path(commit_editmsg), 0) < 0) {
+		rollback_index_files();
 		die("could not read commit message\n");
-	if (run_hook(index_file, "commit-msg", commit_editmsg))
+	}
+	if (run_hook(index_file, "commit-msg", commit_editmsg)) {
+		rollback_index_files();
 		exit(1);
+	}
 	stripspace(&sb, 1);
-	if (sb.len < header_len ||
-	    message_is_empty(&sb, header_len))
+	if (sb.len < header_len || message_is_empty(&sb, header_len)) {
+		rollback_index_files();
 		die("* no commit message?  aborting commit.");
+	}
 	strbuf_addch(&sb, '\0');
 	if (is_encoding_utf8(git_commit_encoding) && !is_utf8(sb.buf))
 		fprintf(stderr, commit_utf8_warn);
 
-	if (write_sha1_file(sb.buf, sb.len - 1, commit_type, commit_sha1))
+	if (write_sha1_file(sb.buf, sb.len - 1, commit_type, commit_sha1)) {
+		rollback_index_files();
 		die("failed to write commit object");
+	}
 
 	ref_lock = lock_any_ref_for_update("HEAD",
 					   initial_commit ? NULL : head_sha1,
@@ -620,21 +784,22 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
 	strbuf_insert(&sb, 0, reflog_msg, strlen(reflog_msg));
 	strbuf_insert(&sb, strlen(reflog_msg), ": ", 2);
 
-	if (!ref_lock)
+	if (!ref_lock) {
+		rollback_index_files();
 		die("cannot lock HEAD ref");
-	if (write_ref_sha1(ref_lock, commit_sha1, sb.buf) < 0)
+	}
+	if (write_ref_sha1(ref_lock, commit_sha1, sb.buf) < 0) {
+		rollback_index_files();
 		die("cannot update HEAD ref");
+	}
 
 	unlink(git_path("MERGE_HEAD"));
 	unlink(git_path("MERGE_MSG"));
 
-	if (lock_file.filename[0] && commit_locked_index(&lock_file))
-		die("failed to write new index");
+	commit_index_files();
 
 	rerere();
-
-	run_hook(index_file, "post-commit", NULL);
-
+	run_hook(get_index_file(), "post-commit", NULL);
 	if (!quiet)
 		print_summary(prefix, commit_sha1);
 
-- 
1.5.3.5.1815.g9445b

^ permalink raw reply related

* [PATCH] Export three helper functions from ls-files
From: Junio C Hamano @ 2007-11-18 10:21 UTC (permalink / raw)
  To: git
In-Reply-To: <1195381287-26823-1-git-send-email-gitster@pobox.com>

This exports three helper functions from ls-files.

 * pathspec_match() checks if a given path matches a set of pathspecs
   and optionally records which pathspec was used.  This function used
   to be called "match()" but renamed to be a bit less vague.

 * report_path_error() takes a set of pathspecs and the record
   pathspec_match() above leaves, and gives error message.  This
   was split out of the main function of ls-files.

 * overlay_tree_on_cache() takes a tree-ish (typically "HEAD")
   and overlays it on the current in-core index.  By iterating
   over the resulting index, the caller can find out the paths
   in either the index or the HEAD.  This function used to be
   called "overlay_tree()" but renamed to be a bit more
   descriptive.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin-ls-files.c |   98 +++++++++++++++++++++++++++------------------------
 cache.h            |    6 +++
 2 files changed, 58 insertions(+), 46 deletions(-)

diff --git a/builtin-ls-files.c b/builtin-ls-files.c
index e0b856f..be485bb 100644
--- a/builtin-ls-files.c
+++ b/builtin-ls-files.c
@@ -38,28 +38,28 @@ static const char *tag_modified = "";
 
 
 /*
- * Match a pathspec against a filename. The first "len" characters
+ * Match a pathspec against a filename. The first "skiplen" characters
  * are the common prefix
  */
-static int match(const char **spec, char *ps_matched,
-		 const char *filename, int len)
+int pathspec_match(const char **spec, char *ps_matched,
+		   const char *filename, int skiplen)
 {
 	const char *m;
 
 	while ((m = *spec++) != NULL) {
-		int matchlen = strlen(m + len);
+		int matchlen = strlen(m + skiplen);
 
 		if (!matchlen)
 			goto matched;
-		if (!strncmp(m + len, filename + len, matchlen)) {
-			if (m[len + matchlen - 1] == '/')
+		if (!strncmp(m + skiplen, filename + skiplen, matchlen)) {
+			if (m[skiplen + matchlen - 1] == '/')
 				goto matched;
-			switch (filename[len + matchlen]) {
+			switch (filename[skiplen + matchlen]) {
 			case '/': case '\0':
 				goto matched;
 			}
 		}
-		if (!fnmatch(m + len, filename + len, 0))
+		if (!fnmatch(m + skiplen, filename + skiplen, 0))
 			goto matched;
 		if (ps_matched)
 			ps_matched++;
@@ -80,7 +80,7 @@ static void show_dir_entry(const char *tag, struct dir_entry *ent)
 	if (len >= ent->len)
 		die("git-ls-files: internal error - directory entry not superset of prefix");
 
-	if (pathspec && !match(pathspec, ps_matched, ent->name, len))
+	if (pathspec && !pathspec_match(pathspec, ps_matched, ent->name, len))
 		return;
 
 	fputs(tag, stdout);
@@ -185,7 +185,7 @@ static void show_ce_entry(const char *tag, struct cache_entry *ce)
 	if (len >= ce_namelen(ce))
 		die("git-ls-files: internal error - cache entry not superset of prefix");
 
-	if (pathspec && !match(pathspec, ps_matched, ce->name, len))
+	if (pathspec && !pathspec_match(pathspec, ps_matched, ce->name, len))
 		return;
 
 	if (tag && *tag && show_valid_bit &&
@@ -331,7 +331,7 @@ static const char *verify_pathspec(const char *prefix)
  * that were given from the command line.  We are not
  * going to write this index out.
  */
-static void overlay_tree(const char *tree_name, const char *prefix)
+void overlay_tree_on_cache(const char *tree_name, const char *prefix)
 {
 	struct tree *tree;
 	unsigned char sha1[20];
@@ -384,6 +384,42 @@ static void overlay_tree(const char *tree_name, const char *prefix)
 	}
 }
 
+int report_path_error(const char *ps_matched, const char **pathspec, int prefix_offset)
+{
+	/*
+	 * Make sure all pathspec matched; otherwise it is an error.
+	 */
+	int num, errors = 0;
+	for (num = 0; pathspec[num]; num++) {
+		int other, found_dup;
+
+		if (ps_matched[num])
+			continue;
+		/*
+		 * The caller might have fed identical pathspec
+		 * twice.  Do not barf on such a mistake.
+		 */
+		for (found_dup = other = 0;
+		     !found_dup && pathspec[other];
+		     other++) {
+			if (other == num || !ps_matched[other])
+				continue;
+			if (!strcmp(pathspec[other], pathspec[num]))
+				/*
+				 * Ok, we have a match already.
+				 */
+				found_dup = 1;
+		}
+		if (found_dup)
+			continue;
+
+		error("pathspec '%s' did not match any file(s) known to git.",
+		      pathspec[num] + prefix_offset);
+		errors++;
+	}
+	return errors;
+}
+
 static const char ls_files_usage[] =
 	"git-ls-files [-z] [-t] [-v] (--[cached|deleted|others|stage|unmerged|killed|modified])* "
 	"[ --ignored ] [--exclude=<pattern>] [--exclude-from=<file>] "
@@ -563,47 +599,17 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
 		 */
 		if (show_stage || show_unmerged)
 			die("ls-files --with-tree is incompatible with -s or -u");
-		overlay_tree(with_tree, prefix);
+		overlay_tree_on_cache(with_tree, prefix);
 	}
 	show_files(&dir, prefix);
 
 	if (ps_matched) {
-		/* We need to make sure all pathspec matched otherwise
-		 * it is an error.
-		 */
-		int num, errors = 0;
-		for (num = 0; pathspec[num]; num++) {
-			int other, found_dup;
-
-			if (ps_matched[num])
-				continue;
-			/*
-			 * The caller might have fed identical pathspec
-			 * twice.  Do not barf on such a mistake.
-			 */
-			for (found_dup = other = 0;
-			     !found_dup && pathspec[other];
-			     other++) {
-				if (other == num || !ps_matched[other])
-					continue;
-				if (!strcmp(pathspec[other], pathspec[num]))
-					/*
-					 * Ok, we have a match already.
-					 */
-					found_dup = 1;
-			}
-			if (found_dup)
-				continue;
-
-			error("pathspec '%s' did not match any file(s) known to git.",
-			      pathspec[num] + prefix_offset);
-			errors++;
-		}
-
-		if (errors)
+		int bad;
+		bad = report_path_error(ps_matched, pathspec, prefix_offset);
+		if (bad)
 			fprintf(stderr, "Did you forget to 'git add'?\n");
 
-		return errors ? 1 : 0;
+		return bad ? 1 : 0;
 	}
 
 	return 0;
diff --git a/cache.h b/cache.h
index f0a25c7..a84f343 100644
--- a/cache.h
+++ b/cache.h
@@ -603,4 +603,10 @@ extern int diff_auto_refresh_index;
 /* match-trees.c */
 void shift_tree(const unsigned char *, const unsigned char *, unsigned char *, int);
 
+
+/* ls-files */
+int pathspec_match(const char **spec, char *matched, const char *filename, int skiplen);
+int report_path_error(const char *ps_matched, const char **pathspec, int prefix_offset);
+void overlay_tree_on_cache(const char *tree_name, const char *prefix);
+
 #endif /* CACHE_H */
-- 
1.5.3.5.1815.g9445b

^ permalink raw reply related

* [PATCH] Fix add_files_to_cache() to take pathspec, not user specified list of files
From: Junio C Hamano @ 2007-11-18 10:21 UTC (permalink / raw)
  To: git
In-Reply-To: <1195381287-26823-2-git-send-email-gitster@pobox.com>

This separates the logic to limit the extent of change to the
index by where you are (controlled by "prefix") and what you
specify from the command line (controlled by "pathspec").

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin-add.c |    8 +++++---
 cache.h       |    4 +++-
 commit.h      |    1 -
 3 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/builtin-add.c b/builtin-add.c
index 45b14e8..16f8557 100644
--- a/builtin-add.c
+++ b/builtin-add.c
@@ -111,12 +111,12 @@ static void update_callback(struct diff_queue_struct *q,
 	}
 }
 
-void add_files_to_cache(int verbose, const char *prefix, const char **files)
+void add_files_to_cache(int verbose, const char *prefix, const char **pathspec)
 {
 	struct rev_info rev;
 	init_revisions(&rev, prefix);
 	setup_revisions(0, NULL, &rev, NULL);
-	rev.prune_data = get_pathspec(prefix, files);
+	rev.prune_data = pathspec;
 	rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
 	rev.diffopt.format_callback = update_callback;
 	rev.diffopt.format_callback_data = &verbose;
@@ -198,9 +198,11 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 	newfd = hold_locked_index(&lock_file, 1);
 
 	if (take_worktree_changes) {
+		const char **pathspec;
 		if (read_cache() < 0)
 			die("index file corrupt");
-		add_files_to_cache(verbose, prefix, argv);
+		pathspec = get_pathspec(prefix, argv);
+		add_files_to_cache(verbose, prefix, pathspec);
 		goto finish;
 	}
 
diff --git a/cache.h b/cache.h
index a84f343..24e7b72 100644
--- a/cache.h
+++ b/cache.h
@@ -597,13 +597,15 @@ extern void trace_argv_printf(const char **argv, int count, const char *format,
 extern int convert_to_git(const char *path, const char *src, size_t len, struct strbuf *dst);
 extern int convert_to_working_tree(const char *path, const char *src, size_t len, struct strbuf *dst);
 
+/* add */
+void add_files_to_cache(int verbose, const char *prefix, const char **pathspec);
+
 /* diff.c */
 extern int diff_auto_refresh_index;
 
 /* match-trees.c */
 void shift_tree(const unsigned char *, const unsigned char *, unsigned char *, int);
 
-
 /* ls-files */
 int pathspec_match(const char **spec, char *matched, const char *filename, int skiplen);
 int report_path_error(const char *ps_matched, const char **pathspec, int prefix_offset);
diff --git a/commit.h b/commit.h
index 13b5372..e22aa77 100644
--- a/commit.h
+++ b/commit.h
@@ -132,7 +132,6 @@ extern struct commit_list *get_shallow_commits(struct object_array *heads,
 int in_merge_bases(struct commit *, struct commit **, int);
 
 extern int interactive_add(void);
-extern void add_files_to_cache(int verbose, const char *prefix, const char **files);
 extern int rerere(void);
 
 #endif /* COMMIT_H */
-- 
1.5.3.5.1815.g9445b

^ permalink raw reply related

* [PATCH] file_exists(): dangling symlinks do exist
From: Junio C Hamano @ 2007-11-18 10:21 UTC (permalink / raw)
  To: git

This function is used to see if a path given by the user does exist
on the filesystem.  A symbolic link that does not point anywhere does
exist but running stat() on it would yield an error, and it incorrectly
said it does not exist.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 dir.c |    7 +++----
 1 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/dir.c b/dir.c
index 01790ab..87e5dec 100644
--- a/dir.c
+++ b/dir.c
@@ -688,11 +688,10 @@ int read_directory(struct dir_struct *dir, const char *path, const char *base, i
 	return dir->nr;
 }
 
-int
-file_exists(const char *f)
+int file_exists(const char *f)
 {
-  struct stat sb;
-  return stat(f, &sb) == 0;
+	struct stat sb;
+	return lstat(f, &sb) == 0;
 }
 
 /*
-- 
1.5.3.5.1815.g9445b

^ permalink raw reply related

* Re: [PATCH] fetch-pack: Prepare for a side-band demultiplexer in a thread.
From: Junio C Hamano @ 2007-11-18 10:16 UTC (permalink / raw)
  To: Johannes Sixt; +Cc: git
In-Reply-To: <200711181036.14565.johannes.sixt@telecom.at>

Johannes Sixt <johannes.sixt@telecom.at> writes:

>> If the rationale was "running in a thread is more natural on the
>> platform", I would understand it.
>
> Please take it as such.
>
>> But "_must_ run because there is no fork(2)" solicits a "Huh?
>> How does Cygwin does it then?" from me.
>
> Alex has answered this. We are not going to copy Cygwin's fork() into git.

Wholeheartedly agree, and I feel dirty after looking at that
thing.  Nothing against Cygwin folks, of course.

The reason I wanted to close pipes as early as possible was
because I did not want to get bitten by "read() waiting forever
for EOF due to an extra unclosed fd on the writer end of the
pipe() without the writer not writing anything to it" problem,
which is an often-seen mistake.

As long as you did not introduce that problem the change is fine
by me.

^ permalink raw reply

* Re: [PATCH v4] user-manual: Add section "Why bisecting merge commits can be harder ..."
From: Steffen Prohaska @ 2007-11-18  9:47 UTC (permalink / raw)
  To: J. Bruce Fields
  Cc: Junio C Hamano, Benoit Sigoure, Andreas Ericsson, Johannes Sixt,
	git
In-Reply-To: <20071118035934.GA29374@fieldses.org>


On Nov 18, 2007, at 4:59 AM, J. Bruce Fields wrote:

> On Sat, Nov 10, 2007 at 02:49:54PM +0100, Steffen Prohaska wrote:
>> +[[bisect-merges]]
>> +Why bisecting merge commits can be harder than bisecting linear  
>> history
>> +-------------------------------------------------------------------- 
>> ---
>> +
>> +This section discusses how gitlink:git-bisect[1] plays
>> +with differently shaped histories.  The text is based upon
>> +an email by Junio C. Hamano to the git mailing list
>> +(link:http://marc.info/?l=git&m=119403257315527&w=2[link:http:// 
>> marc.info/?l=git&m=119403257315527&w=2]).
>> +It was adapted for the user manual.
>
> This is not the only text that's been taken from someplace else,  
> but if
> we attributed them all in the text it would get a little  
> cumbersome....
> I think the place for that kind of thing is in the commit message, but
> if we really think we need to include it in the main text, we could  
> add
> a separate "'acknowledgements" section.

ack for this change.

And a general comment: I had two purposes in\x05 mind when I
added this paragraph
1) Attribution;
2) Giving a reference to the original discussion.  If someone disagrees,
    or has further questions, the original discussion on the mailing
    list could be useful.

I believe the commit message is sufficient for attribution.
I don't think we need more.  Maybe if the manual goes to print
we need to reconsider.  But who know if this ever will happen.

However, adding a References section with links to other
resources could be a useful thing.  Such resources could give
additional information, without sacrificing the conciseness of
the manual.  An example are links to the original discussion on
the list.  Often they contain more details, which may sometimes
be useful.

Does asciidoc provide a mechanism for this?  Something like
\cite{} in LaTeX.



>> +
>> +Using gitlink:git-bisect[1] on a history with merges can be
>> +challenging.  Bisecting through merges is not a technical
>> +problem. The real problem is what to do when the culprit turns
>> +out to be a merge commit.  How to spot what really is wrong, and
>> +figure out how to fix it.  The problem is not for the tool but
>> +for the human, and it is real.
>
> I think we can pare that down a little.

 From your 7df716bec6bf6e3dafe4c36a6313a4346de2585a

+The gitlink:git-bisect[1] commands deals fine with history that  
includes
+merge commits.  However, when the final commit that ends on is a merge
+commit, the user may need to work harder than usual to figure out
+exactly what the problem was.

If you don't take the text below, first line: s/commands/command/

I'd reverse the order of the sentences.  The section is about
the difficulty, not about praising git-bisect.  How about

When the final commit that a bisect ends on is a merge commit,
the user may need to work harder than usual to figure out
exactly what the problem was.  This is not a technical
problem.  In principle, the gitlink:git-bisect[1] command
deals fine with history that includes merge commits.

It's your call.  I'm also fine with your version.


>> +
>> +Imagine this history:
>> +
>> +................................................
>> +      ---Z---o---X---...---o---A---C---D
>> +          \                       /
>> +           o---o---Y---...---o---B
>> +................................................
>> +
>> +Suppose that on the upper development line, the meaning of one
>> +of the functions that existed at Z was changed at commit X.  The
>> +commits from Z leading to A change both the function's
>> +implementation and all calling sites that existed at Z, as well
>> +as new calling sites they add, to be consistent.  There is no
>> +bug at A.
>> +
>> +Suppose that in the meantime the lower development line somebody
>> +added a new calling site for that function at commit Y.  The
>> +commits from Z leading to B all assume the old semantics of that
>> +function and the callers and the callee are consistent with each
>> +other.  There is no bug at B, either.
>> +
>> +Suppose further that the two development lines were merged at C
>> +and there was no textual conflict with this three way merge.
>> +The result merged cleanly.
>> +
>> +Now, during bisect you find that the merge C is broken.  You
>> +started to bisect, because you found D is bad and you know Z was
>> +good.  The breakage is understandable, as at C, the new calling
>> +site of the function added by the lower branch is not converted
>> +to the new semantics, while all the other calling sites that
>> +already existed at Z would have been converted by the merge.  The
>> +new calling site has semantic adjustment needed, but you do not
>> +know that yet.
>> +

 From your 7df716bec6bf6e3dafe4c36a6313a4346de2585a

+Nevertheless, the code at C is broken, because the callers added
+on the lower line of development have not been converted to the new
+semantics introduced on the upper line of development.  So if all
+you know is that D was bad, Z was good, and that a

s/a//?  I'm not sure; you are the native speaker ;)

+gitlink:git-bisect[1] identified C as the culprit, how will you
+figure out that the problem was due to this change in semantics?



>> +You need to find out what is the cause of the breakage by looking
>> +at the merge commit C and the history leading to it.  How would
>> +you do that?
>> +
>> +Both "git diff A C" and "git diff B C" would be an enormous patch.
>> +Each of them essentially shows the whole change on each branch
>> +since they diverged.  The developers may have well behaved to
>> +create good commits that follow the "commit small, commit often,
>> +commit well contained units" mantra, and each individual commit
>> +leading from Z to A and from Z to B may be easy to review and
>> +understand, but looking at these small and easily reviewable
>> +steps alone would not let you spot the breakage.  You need to
>> +have a global picture of what the upper branch did (and
>> +among many, one of them is to change the semantics of that
>> +particular function) and look first at the huge "diff A C"
>> +(which shows the change the lower branch introduces), and see if
>> +that huge change is consistent with what have been done between
>> +Z and A.
>> +

 From your 7df716bec6bf6e3dafe4c36a6313a4346de2585a

+When the result of a git-bisect is a non-merge commit, you should
+normally be able to discover the problem be examining just that commit.

s/be examining/by examining/

+Developers can make this easy by breaking their changes into small
+self-contained commits.  That won't help in the case above, however,
+because the problem isn't obvious from examination of any single
+commit; instead, a global view of the development is required.  To
+make matters worse, the change in semantics in the problematic
+function may be just one small part of the changes in the upper
+line of development.
+



>> +On the other hand, if you did not merge at C but rebased the
>> +history between Z to B on top of A, you would have get this
>> +linear history:
>> +
>> +................................................................
>> +    ---Z---o---X--...---o---A---o---o---Y*--...---o---B*--D*
>> +................................................................
>> +
>> +Bisecting between Z and D* would hit a single culprit commit Y*
>> +instead.  This tends to be easier to understand why it is broken.
>> +
>> +For this reason, many experienced git users, even when they are
>> +working on an otherwise merge-heavy project, keep the histories
>> +linear by rebasing their work on top of public upstreams before
>> +publishing.
>
> I'd say "partly for this reason", as I don't think this is the only
> reason people do that.
>
> I've done the above revisions and a few others and pushed them to
>
> 	git://linux-nfs.org/~bfields/git.git maint
>
> I'll take another look in the morning.

Besides the minor fixes above, ack from me.  We already spend
a lot of time on this section.  It improved compared to the
first version and I think it's now ready for the manual.

	Steffen

^ permalink raw reply

* Re: preserving mtime
From: Jan Hudec @ 2007-11-18  9:40 UTC (permalink / raw)
  To: Mike Hommey; +Cc: Wayne Davison, Andreas Ericsson, git
In-Reply-To: <20071118084511.GC16863@glandium.org>

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

On Sun, Nov 18, 2007 at 09:45:11 +0100, Mike Hommey wrote:
> On Sat, Nov 17, 2007 at 10:22:36AM -0800, Wayne Davison wrote:
> > On Fri, Nov 16, 2007 at 11:15:34AM +0100, Andreas Ericsson wrote:
> > >> is it possible to tell git to preserve the file modification time in
> > >> a checked out copy?
> > 
> > > Fabrizio Pollastri wrote:
> > > No. Doing so would seriously break build-systems.
> > 
> > I wish that the initial clone would set the modification time to the
> > commit time.  It would make the intial checkout have a more accurate
> > representation of when a file was last changed instead of all files
> > being set to the clone date.  Then, files that are being updated would
> > get their time set as they do now.  I supposed I'll just use the handy
> > git-set-file-times script (mentioned in another reply) every time I do
> > a clone.
> 
> For completeness, it would make sense to do so every time you git
> checkout (like, when switching branches).

 - That would still screw-up make hard. You know, checking out does NOT
   delete any untracked files.

 - There is no such thing as last modification time in git. Because there is
   no file history in git. (Besides, what would be last modification time of
   a file that was last modified in two parents, for example?)

-- 
						 Jan 'Bulb' Hudec <bulb@ucw.cz>

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

^ permalink raw reply

* Re: [PATCH] fetch-pack: Prepare for a side-band demultiplexer in a thread.
From: Johannes Sixt @ 2007-11-18  9:36 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano
In-Reply-To: <7vtznkz8nw.fsf@gitster.siamese.dyndns.org>

On Sunday 18 November 2007 01:42, Junio C Hamano wrote:
> Johannes Sixt <johannes.sixt@telecom.at> writes:
> > 	This change again originates from the MinGW port. Since we don't
> > 	have fork(2) on Windows, we must run the sideband demultiplexer
> > 	in a thread.
>
> If the rationale was "running in a thread is more natural on the
> platform", I would understand it.

Please take it as such.

> But "_must_ run because there is no fork(2)" solicits a "Huh?
> How does Cygwin does it then?" from me.

Alex has answered this. We are not going to copy Cygwin's fork() into git.

-- Hannes

^ permalink raw reply

* Re: preserving mtime
From: Martin Langhoff @ 2007-11-18  9:34 UTC (permalink / raw)
  To: Mike Hommey; +Cc: Wayne Davison, Andreas Ericsson, git
In-Reply-To: <20071118084511.GC16863@glandium.org>

On Nov 18, 2007 9:45 PM, Mike Hommey <mh@glandium.org> wrote:
> On Sat, Nov 17, 2007 at 10:22:36AM -0800, Wayne Davison wrote:
> > I wish that the initial clone would set the modification time to the
> > commit time.  It would make the intial checkout have a more accurate
> > representation of when a file was last changed instead of all files
...
> For completeness, it would make sense to do so every time you git
> checkout (like, when switching branches).

I do hope anyone doing those things is _very_ aware that the mtime
metadata has a specific meaning -- when did this specific file in this
filesystem last change -- and is used by many tools in that sense. You
are trying to use it for something else. Lots of things will break.

Like incremental backups, for example.

So no no NO. Not recommended. Stuff will break in new and surprising
ways. It'd be trivial to write a quick script that shows the data you
want from git in Perl/Python/etc. But don't use mtime. It's used for
other stuff. Actually used for other stuff. Don't replace that data
with time data you want to see, the actual users of mtime will break.

cheers,


m

^ permalink raw reply

* [PATCH] Fix warning about bitfield in struct ref
From: Shawn O. Pearce @ 2007-11-18  9:31 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

cache.h:503: warning: type of bit-field 'force' is a GCC extension
cache.h:504: warning: type of bit-field 'merge' is a GCC extension
cache.h:505: warning: type of bit-field 'nonfastforward' is a GCC extension
cache.h:506: warning: type of bit-field 'deletion' is a GCC extension

So we change it to an 'unsigned int' which is not a GCC extension.

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

diff --git a/cache.h b/cache.h
index ba9178f..65e019e 100644
--- a/cache.h
+++ b/cache.h
@@ -500,10 +500,10 @@ struct ref {
 	struct ref *next;
 	unsigned char old_sha1[20];
 	unsigned char new_sha1[20];
-	unsigned char force : 1;
-	unsigned char merge : 1;
-	unsigned char nonfastforward : 1;
-	unsigned char deletion : 1;
+	unsigned int force:1,
+		merge:1,
+		nonfastforward:1,
+		deletion:1;
 	enum {
 		REF_STATUS_NONE = 0,
 		REF_STATUS_OK,
-- 
1.5.3.5.1794.g083e

^ 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