Git development
 help / color / mirror / Atom feed
* Re: [PATCH 2/2] repo-config: learn the flag "--no-local"
From: Aneesh Kumar K.V @ 2006-06-08 15:35 UTC (permalink / raw)
  To: Karl Hasselstr?m; +Cc: Lukas Sandstr?m, Git Mailing List, junkio
In-Reply-To: <20060608133747.GA15374@diana.vm.bytemark.co.uk>

On Thu, Jun 08, 2006 at 03:37:47PM +0200, Karl Hasselstr?m wrote:
> On 2006-06-08 13:41:04 +0200, Johannes Schindelin wrote:
> 
> My vote goes to --no-local, but only if we also get a --no-no-local
> flag with the opposite meaning. Otherwise, I'd prefer --global. :-)
> 


I guess it makes much sense to rename the command to git-config and say 

git config  alias.l  -> for golbal config 
git config --repo alias.l -> for repo specific config 

-aneesh

^ permalink raw reply

* Re: [PATCH 2/2] repo-config: learn the flag "--no-local"
From: Junio C Hamano @ 2006-06-08 16:25 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Lukas Sandström, Git Mailing List, junkio
In-Reply-To: <Pine.LNX.4.63.0606081340230.25911@wbgn013.biozentrum.uni-wuerzburg.de>

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

>> Johannes Schindelin wrote:
> On Thu, 8 Jun 2006, Lukas Sandström wrote:
>> > Since there is a global config now, we need a way to access it
>> > conveniently. Now you can say
>> > 
>> > 	git repo-config --no-local alias.l "log --stat -M ORIG_HEAD.."
>> > 
>> > to set the alias globally (it will be stored in ~/.gitconfig).
>> 
>> Wouldn't it make more sense to call the flag --global ?
>
> Sure, why not? Other opinions? (I will not add a test case until this is 
> resolved! ;-)

The wording "--no-local" means you are looking at things
relative to a particular repository.  I.e. some configuration
variables come from repository-local file, and others from
somewhere else.  But I do not think that somewhere else is
"global".  We are reading from $HOME, which is different
depending on who is interacting with that same repository.  So I
would probably call the other one "--user" or something if I
were force to pick name.

But as you know, I am horrible at picking names, so please don't
stop this from coming up with a good name the list can agree
upon.

^ permalink raw reply

* Re: [PATCH 2/2] repo-config: learn the flag "--no-local"
From: Sean @ 2006-06-08 16:36 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Johannes.Schindelin, lukass, git, junkio
In-Reply-To: <7v1wtzaa26.fsf@assigned-by-dhcp.cox.net>

On Thu, 08 Jun 2006 09:25:53 -0700
Junio C Hamano <junkio@cox.net> wrote:


> The wording "--no-local" means you are looking at things
> relative to a particular repository.  I.e. some configuration
> variables come from repository-local file, and others from
> somewhere else.  But I do not think that somewhere else is
> "global".  We are reading from $HOME, which is different
> depending on who is interacting with that same repository.  So I
> would probably call the other one "--user" or something if I
> were force to pick name.

--user or --home makes a lot of sense.  Alternatively you could
just be explicit: --config=~ or --config=/etc/gitconfig where
/.gitconfig is automatically appended to the path if it ends in
a directory name.

Sean

^ permalink raw reply

* Re: HEAD branch duplicated in remotes/origin
From: Junio C Hamano @ 2006-06-08 16:39 UTC (permalink / raw)
  To: Uwe Zeisberger; +Cc: git
In-Reply-To: <20060608123337.GA12456@informatik.uni-freiburg.de>

Uwe Zeisberger <zeisberg@informatik.uni-freiburg.de> writes:

> I wonder if this is easier not to add the other duplicate.

Unfortunately the above is probably easier.  The other duplicate
is coming from the lowlevel code that makes sure each of the
fetch-pack parameters is not used to match more than once.  We
should fix it eventually, though.

^ permalink raw reply

* Re: [PATCH 1/2]: amendment
From: Junio C Hamano @ 2006-06-08 16:51 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: git
In-Reply-To: <Pine.LNX.4.63.0606081719400.27335@wbgn013.biozentrum.uni-wuerzburg.de>

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

> I completely forgot that with a global config, it makes sense to have 
> aliases even if we are not in a git repository.
>
> So, in git.c, handle_alias() the "if (nongit)" makes no sense any longer. 
> If I have to revise the patch anyway, I will include the change, but if 
> you decide to take it, please change that.
>
> Ciao,
> Dscho
>
> P.S.: There might be other users (such as git-peek-remote) who want that 
> change, too.

Well, this is pretty late in the 1.4.0 game and honestly I am
pretty reluctant to merge this in, push 1.4.0 out in 48 hours
and leave for nearly a week.

So either we would reschedule 1.4.0 and shoot for June 24th, or
do 1.4.0 this weekend as planned, and leave this as the first
item (perhaps the second, after applying many small clean-ups
I've privately received, which I haven't acted on other than
quickly reviewing and asking the submitter to rebase and resend
cc'ing the list) in the post-1.4.0 development cycle.  This
potentially is a candidate to backport to 1.4.X series.

My preference is to cook this in "next" for a while and merge it
post 1.4.0.

^ permalink raw reply

* Re: [PATCH 1/2]: amendment
From: Junio C Hamano @ 2006-06-08 16:52 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: git
In-Reply-To: <Pine.LNX.4.63.0606081719400.27335@wbgn013.biozentrum.uni-wuerzburg.de>

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

> I completely forgot that with a global config, it makes sense to have 
> aliases even if we are not in a git repository.
>
> So, in git.c, handle_alias() the "if (nongit)" makes no sense any longer. 
> If I have to revise the patch anyway, I will include the change, but if 
> you decide to take it, please change that.
>
> Ciao,
> Dscho
>
> P.S.: There might be other users (such as git-peek-remote) who want that 
> change, too.

Well, this is pretty late in the 1.4.0 game and honestly I am
pretty reluctant to merge this in, push 1.4.0 out in 48 hours
and leave for nearly a week.

So either we would reschedule 1.4.0 and shoot for June 24th, or
do 1.4.0 this weekend as planned, and leave this as the first
item (perhaps the second, after applying many small clean-ups
I've privately received, which I haven't acted on other than
quickly reviewing and asking the submitter to rebase and resend
cc'ing the list) in the post-1.4.0 development cycle.  This
potentially is a candidate to backport to 1.4.X series.

My preference is to cook this in "next" for a while and merge it
post 1.4.0.

^ permalink raw reply

* [PATCH] Implement git-branch and git-merge-base as built-ins.
From: Kristian Høgsberg @ 2006-06-08 17:49 UTC (permalink / raw)
  To: git

This patch is more or less a straight port of git-branch from shell
script to C.  Branch deletion uses git-merge-base to check if it is safe
to delete a branch, so I changed merge-base.c to export this functionality
as a for_each_merge_base() iterator.  As a side effect, git-merge-base is
now also a built-in command.

---

6b90d7b7af4bf577ccfeebef1f736e75631b052d
 Makefile         |   13 +++--
 builtin-branch.c |  154 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 builtin.h        |    2 +
 commit.h         |    5 ++
 git-branch.sh    |  120 ------------------------------------------
 git.c            |    4 +
 merge-base.c     |   34 ++++++++----
 7 files changed, 194 insertions(+), 138 deletions(-)

diff --git a/Makefile b/Makefile
index 5373986..a709e40 100644
--- a/Makefile
+++ b/Makefile
@@ -113,7 +113,7 @@ SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powe
 ### --- END CONFIGURATION SECTION ---
 
 SCRIPT_SH = \
-	git-bisect.sh git-branch.sh git-checkout.sh \
+	git-bisect.sh git-checkout.sh \
 	git-cherry.sh git-clean.sh git-clone.sh git-commit.sh \
 	git-fetch.sh \
 	git-format-patch.sh git-ls-remote.sh \
@@ -155,7 +155,7 @@ PROGRAMS = \
 	git-diff-index$X git-diff-stages$X \
 	git-diff-tree$X git-fetch-pack$X git-fsck-objects$X \
 	git-hash-object$X git-index-pack$X git-init-db$X git-local-fetch$X \
-	git-ls-files$X git-ls-tree$X git-mailinfo$X git-merge-base$X \
+	git-ls-files$X git-ls-tree$X git-mailinfo$X \
 	git-merge-index$X git-mktag$X git-mktree$X git-pack-objects$X git-patch-id$X \
 	git-peek-remote$X git-prune-packed$X git-read-tree$X \
 	git-receive-pack$X git-rev-parse$X \
@@ -170,7 +170,8 @@ PROGRAMS = \
 
 BUILT_INS = git-log$X git-whatchanged$X git-show$X \
 	git-count-objects$X git-diff$X git-push$X \
-	git-grep$X git-add$X git-rev-list$X git-check-ref-format$X
+	git-grep$X git-add$X git-rev-list$X git-check-ref-format$X \
+	git-branch$X git-merge-base$X
 
 # what 'all' will build and 'install' will install, in gitexecdir
 ALL_PROGRAMS = $(PROGRAMS) $(SIMPLE_PROGRAMS) $(SCRIPTS)
@@ -214,11 +215,13 @@ LIB_OBJS = \
 	server-info.o setup.o sha1_file.o sha1_name.o strbuf.o \
 	tag.o tree.o usage.o config.o environment.o ctype.o copy.o \
 	fetch-clone.o revision.o pager.o tree-walk.o xdiff-interface.o \
+	merge-base.o \
 	$(DIFF_OBJS)
 
 BUILTIN_OBJS = \
-	builtin-log.o builtin-help.o builtin-count.o builtin-diff.o builtin-push.o \
-	builtin-grep.o builtin-add.o builtin-rev-list.o builtin-check-ref-format.o
+	builtin-log.o builtin-help.o builtin-count.o builtin-diff.o \
+	builtin-push.o builtin-grep.o builtin-add.o builtin-rev-list.o \
+	builtin-check-ref-format.o builtin-branch.o
 
 GITLIBS = $(LIB_FILE) $(XDIFF_LIB)
 LIBS = $(GITLIBS) -lz
diff --git a/builtin-branch.c b/builtin-branch.c
new file mode 100644
index 0000000..c7776a3
--- /dev/null
+++ b/builtin-branch.c
@@ -0,0 +1,154 @@
+/*
+ * Builtin "git branch"
+ *
+ * Copyright (c) 2006 Kristian Høgsberg <krh@redhat.com>
+ * Based on git-branch.sh by Junio C Hamano.
+ */
+
+#include "cache.h"
+#include "refs.h"
+#include "commit.h"
+#include "builtin.h"
+
+static const char builtin_branch_usage[] =
+	"git-branch [(-d | -D) <branchname>] | [[-f] <branchname> [<start-point>]] | -r";
+
+
+static int remote_only = 0;
+static const char *head;
+static unsigned char head_sha1[20];
+
+static int find_sha1(struct commit *commit, void *data)
+{
+	return !memcmp(data, commit->object.sha1, sizeof commit->object.sha1);
+}
+
+static void delete_branches(int argc, const char **argv, int force)
+{
+	struct commit *rev1, *rev2;
+	unsigned char sha1[20];
+	const char *p, *name;
+	int i;
+
+	for (i = 0; i < argc; i++) {
+		if (!strcmp(head, argv[i]))
+			die("Cannot delete the branch you are currently on.");
+
+		name = git_path("refs/heads/%s", argv[i]);
+		p = resolve_ref(name, sha1, 1);
+		if (p == NULL)
+			die("Branch '%s' not found.", argv[i]);
+
+		rev1 = lookup_commit_reference(sha1);
+		rev2 = lookup_commit_reference(head_sha1);
+		if (!rev1 || !rev2)
+			die("Couldn't look up commit objects.");
+
+		/* This checks wether the merge bases of branch and
+		 * HEAD contains branch -- which means that the HEAD
+		 * contains everything in both.
+		 */
+
+		if (!force &&
+		    !for_each_merge_base(rev1, rev2, find_sha1, sha1)) {
+			fprintf(stderr,
+				"The branch '%s' is not a strict subset of your current HEAD.\n"
+				"If you are sure you want to delete it, run 'git branch -D %s'.\n",
+				argv[i], argv[i]);
+			exit(1);
+		}
+
+		unlink(name);
+		printf("Deleted branch %s.\n", argv[i]);
+	}
+}
+
+static int show_reference(const char *refname, const unsigned char *sha1)
+{
+	int is_head = !strcmp(refname, head);
+
+	printf("%c %s\n", (is_head ? '*' : ' '), refname);
+
+	return 0;
+}
+
+static void create_branch (const char *name, const char *start, int force)
+{
+	unsigned char sha1[20];
+	char ref[500];
+
+	snprintf (ref, sizeof ref, "heads/%s", name);
+	if (check_ref_format(ref))
+		die("'%s' is not a valid branch name.", name);
+
+	if (resolve_ref(git_path("refs/%s", ref), sha1, 1)) {
+		if (!force)
+			die("A branch named '%s' already exists.", name);
+		else if (!strcmp(head, name))
+			die("Cannot force update the current branch.");
+	}
+
+	if (get_sha1(start, sha1))
+		die("Not a valid branch point: '%s'", start);
+
+	if (write_ref_sha1_unlocked(ref, sha1))
+		die("Failed to create branch: %s.", strerror(errno));
+}
+
+int cmd_branch(int argc, const char **argv, char **envp)
+{
+	int delete = 0, force_delete = 0, force_create = 0;
+	int i, prefix_length;
+	const char *p;
+
+	setup_git_directory();
+	git_config(git_default_config);
+
+	for (i = 1; i < argc; i++) {
+		const char *arg = argv[i];
+
+		if (arg[0] != '-')
+			break;
+		if (!strcmp(arg, "--")) {
+			i++;
+			break;
+		}
+		if (!strcmp(arg, "-d")) {
+			delete = 1;
+			continue;
+		}
+		if (!strcmp(arg, "-D")) {
+			delete = 1;
+			force_delete = 1;
+			continue;
+		}
+		if (!strcmp(arg, "-f")) {
+			force_create = 1;
+			continue;
+		}
+		if (!strcmp(arg, "-r")) {
+			remote_only = 1;
+			continue;
+		}
+		die(builtin_branch_usage);
+	}
+
+	prefix_length = strlen(git_path("refs/heads/"));
+	p = resolve_ref(git_path("HEAD"), head_sha1, 0);
+	if (!p)
+		die("Failed to resolve HEAD as a valid ref");
+	head = strdup(p + prefix_length);
+
+	if (delete)
+		delete_branches(argc - i, argv + i, force_delete);
+	else if (i == argc && remote_only)
+		for_each_remote_ref(show_reference);
+	else if (i == argc)
+		for_each_branch_ref(show_reference);
+	else if (argc - i == 1)
+		create_branch (argv[i], head, force_create);
+	else
+		create_branch (argv[i], argv[i + 1], force_create);
+
+	return 0;
+}
diff --git a/builtin.h b/builtin.h
index 78275ea..0105358 100644
--- a/builtin.h
+++ b/builtin.h
@@ -28,5 +28,7 @@ extern int cmd_grep(int argc, const char
 extern int cmd_add(int argc, const char **argv, char **envp);
 extern int cmd_rev_list(int argc, const char **argv, char **envp);
 extern int cmd_check_ref_format(int argc, const char **argv, char **envp);
+extern int cmd_branch(int argc, const char **argv, char **envp);
+extern int cmd_merge_base(int argc, const char **argv, char **envp);
 
 #endif
diff --git a/commit.h b/commit.h
index 8d7514c..b1a518a 100644
--- a/commit.h
+++ b/commit.h
@@ -104,4 +104,9 @@ struct commit_graft *read_graft_line(cha
 int register_commit_graft(struct commit_graft *, int);
 int read_graft_file(const char *graft_file);
 
+/* merge-base.c */
+int for_each_merge_base(struct commit *rev1, struct commit *rev2,
+			int (*fn)(struct commit *commit, void *data),
+			void  *data);
+
 #endif /* COMMIT_H */
diff --git a/git-branch.sh b/git-branch.sh
deleted file mode 100755
index 134e68c..0000000
--- a/git-branch.sh
+++ /dev/null
@@ -1,120 +0,0 @@
-#!/bin/sh
-
-USAGE='[(-d | -D) <branchname>] | [[-f] <branchname> [<start-point>]] | -r'
-LONG_USAGE='If no arguments, show available branches and mark current branch with a star.
-If one argument, create a new branch <branchname> based off of current HEAD.
-If two arguments, create a new branch <branchname> based off of <start-point>.'
-
-SUBDIRECTORY_OK='Yes'
-. git-sh-setup
-
-headref=$(git-symbolic-ref HEAD | sed -e 's|^refs/heads/||')
-
-delete_branch () {
-    option="$1"
-    shift
-    for branch_name
-    do
-	case ",$headref," in
-	",$branch_name,")
-	    die "Cannot delete the branch you are on." ;;
-	,,)
-	    die "What branch are you on anyway?" ;;
-	esac
-	branch=$(cat "$GIT_DIR/refs/heads/$branch_name") &&
-	    branch=$(git-rev-parse --verify "$branch^0") ||
-		die "Seriously, what branch are you talking about?"
-	case "$option" in
-	-D)
-	    ;;
-	*)
-	    mbs=$(git-merge-base -a "$branch" HEAD | tr '\012' ' ')
-	    case " $mbs " in
-	    *' '$branch' '*)
-		# the merge base of branch and HEAD contains branch --
-		# which means that the HEAD contains everything in both.
-		;;
-	    *)
-		echo >&2 "The branch '$branch_name' is not a strict subset of your current HEAD.
-If you are sure you want to delete it, run 'git branch -D $branch_name'."
-		exit 1
-		;;
-	    esac
-	    ;;
-	esac
-	rm -f "$GIT_DIR/refs/heads/$branch_name"
-	echo "Deleted branch $branch_name."
-    done
-    exit 0
-}
-
-ls_remote_branches () {
-    git-rev-parse --symbolic --all |
-    sed -ne 's|^refs/\(remotes/\)|\1|p' |
-    sort
-}
-
-force=
-while case "$#,$1" in 0,*) break ;; *,-*) ;; *) break ;; esac
-do
-	case "$1" in
-	-d | -D)
-		delete_branch "$@"
-		exit
-		;;
-	-r)
-		ls_remote_branches
-		exit
-		;;
-	-f)
-		force="$1"
-		;;
-	--)
-		shift
-		break
-		;;
-	-*)
-		usage
-		;;
-	esac
-	shift
-done
-
-case "$#" in
-0)
-	git-rev-parse --symbolic --branches |
-	sort |
-	while read ref
-	do
-		if test "$headref" = "$ref"
-		then
-			pfx='*'
-		else
-			pfx=' '
-		fi
-		echo "$pfx $ref"
-	done
-	exit 0 ;;
-1)
-	head=HEAD ;;
-2)
-	head="$2^0" ;;
-esac
-branchname="$1"
-
-rev=$(git-rev-parse --verify "$head") || exit
-
-git-check-ref-format "heads/$branchname" ||
-	die "we do not like '$branchname' as a branch name."
-
-if [ -e "$GIT_DIR/refs/heads/$branchname" ]
-then
-	if test '' = "$force"
-	then
-		die "$branchname already exists."
-	elif test "$branchname" = "$headref"
-	then
-		die "cannot force-update the current branch."
-	fi
-fi
-git update-ref "refs/heads/$branchname" $rev
diff --git a/git.c b/git.c
index 7db5cc1..fb66c0e 100644
--- a/git.c
+++ b/git.c
@@ -53,7 +53,9 @@ static void handle_internal_command(int 
 		{ "grep", cmd_grep },
 		{ "add", cmd_add },
 		{ "rev-list", cmd_rev_list },
-		{ "check-ref-format", cmd_check_ref_format }
+		{ "check-ref-format", cmd_check_ref_format },
+		{ "branch", cmd_branch },
+		{ "merge-base", cmd_merge_base }
 	};
 	int i;
 
diff --git a/merge-base.c b/merge-base.c
index 4856ca0..0aa6ed4 100644
--- a/merge-base.c
+++ b/merge-base.c
@@ -1,6 +1,6 @@
-#include <stdlib.h>
 #include "cache.h"
 #include "commit.h"
+#include "builtin.h"
 
 #define PARENT1 1
 #define PARENT2 2
@@ -167,16 +167,16 @@ static void mark_reachable_commits(struc
 	}
 }
 
-static int merge_base(struct commit *rev1, struct commit *rev2)
+int for_each_merge_base(struct commit *rev1, struct commit *rev2,
+			int (*fn)(struct commit *commit, void *data),
+			void *data)
 {
 	struct commit_list *list = NULL;
 	struct commit_list *result = NULL;
 	struct commit_list *tmp = NULL;
 
-	if (rev1 == rev2) {
-		printf("%s\n", sha1_to_hex(rev1->object.sha1));
-		return 0;
-	}
+	if (rev1 == rev2) 
+		return fn(rev1, data);
 
 	parse_commit(rev1);
 	parse_commit(rev2);
@@ -220,12 +220,13 @@ static int merge_base(struct commit *rev
 
 	while (result) {
 		struct commit *commit = result->item;
+		int retval;
 		result = result->next;
 		if (commit->object.flags & UNINTERESTING)
 			continue;
-		printf("%s\n", sha1_to_hex(commit->object.sha1));
-		if (!show_all)
-			return 0;
+		retval = fn(commit, data);
+		if (retval)
+			return retval;
 		commit->object.flags |= UNINTERESTING;
 	}
 	return 0;
@@ -234,7 +235,13 @@ static int merge_base(struct commit *rev
 static const char merge_base_usage[] =
 "git-merge-base [--all] <commit-id> <commit-id>";
 
-int main(int argc, char **argv)
+static int print_merge_base(struct commit *commit, void *data)
+{
+	printf("%s\n", sha1_to_hex(commit->object.sha1));
+	return show_all ? 0 : 1;
+}
+
+int cmd_merge_base(int argc, const char **argv, char **envp)
 {
 	struct commit *rev1, *rev2;
 	unsigned char rev1key[20], rev2key[20];
@@ -243,7 +250,7 @@ int main(int argc, char **argv)
 	git_config(git_default_config);
 
 	while (1 < argc && argv[1][0] == '-') {
-		char *arg = argv[1];
+		const char *arg = argv[1];
 		if (!strcmp(arg, "-a") || !strcmp(arg, "--all"))
 			show_all = 1;
 		else
@@ -260,5 +267,8 @@ int main(int argc, char **argv)
 	rev2 = lookup_commit_reference(rev2key);
 	if (!rev1 || !rev2)
 		return 1;
-	return merge_base(rev1, rev2);
+
+	for_each_merge_base(rev1, rev2, print_merge_base, NULL);
+
+	return 0;
 }

6b90d7b7af4bf577ccfeebef1f736e75631b052d
diff --git a/Makefile b/Makefile
index 5373986..a709e40 100644
--- a/Makefile
+++ b/Makefile
@@ -113,7 +113,7 @@ SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powe
 ### --- END CONFIGURATION SECTION ---
 
 SCRIPT_SH = \
-	git-bisect.sh git-branch.sh git-checkout.sh \
+	git-bisect.sh git-checkout.sh \
 	git-cherry.sh git-clean.sh git-clone.sh git-commit.sh \
 	git-fetch.sh \
 	git-format-patch.sh git-ls-remote.sh \
@@ -155,7 +155,7 @@ PROGRAMS = \
 	git-diff-index$X git-diff-stages$X \
 	git-diff-tree$X git-fetch-pack$X git-fsck-objects$X \
 	git-hash-object$X git-index-pack$X git-init-db$X git-local-fetch$X \
-	git-ls-files$X git-ls-tree$X git-mailinfo$X git-merge-base$X \
+	git-ls-files$X git-ls-tree$X git-mailinfo$X \
 	git-merge-index$X git-mktag$X git-mktree$X git-pack-objects$X git-patch-id$X \
 	git-peek-remote$X git-prune-packed$X git-read-tree$X \
 	git-receive-pack$X git-rev-parse$X \
@@ -170,7 +170,8 @@ PROGRAMS = \
 
 BUILT_INS = git-log$X git-whatchanged$X git-show$X \
 	git-count-objects$X git-diff$X git-push$X \
-	git-grep$X git-add$X git-rev-list$X git-check-ref-format$X
+	git-grep$X git-add$X git-rev-list$X git-check-ref-format$X \
+	git-branch$X git-merge-base$X
 
 # what 'all' will build and 'install' will install, in gitexecdir
 ALL_PROGRAMS = $(PROGRAMS) $(SIMPLE_PROGRAMS) $(SCRIPTS)
@@ -214,11 +215,13 @@ LIB_OBJS = \
 	server-info.o setup.o sha1_file.o sha1_name.o strbuf.o \
 	tag.o tree.o usage.o config.o environment.o ctype.o copy.o \
 	fetch-clone.o revision.o pager.o tree-walk.o xdiff-interface.o \
+	merge-base.o \
 	$(DIFF_OBJS)
 
 BUILTIN_OBJS = \
-	builtin-log.o builtin-help.o builtin-count.o builtin-diff.o builtin-push.o \
-	builtin-grep.o builtin-add.o builtin-rev-list.o builtin-check-ref-format.o
+	builtin-log.o builtin-help.o builtin-count.o builtin-diff.o \
+	builtin-push.o builtin-grep.o builtin-add.o builtin-rev-list.o \
+	builtin-check-ref-format.o builtin-branch.o
 
 GITLIBS = $(LIB_FILE) $(XDIFF_LIB)
 LIBS = $(GITLIBS) -lz
diff --git a/builtin-branch.c b/builtin-branch.c
new file mode 100644
index 0000000..c7776a3
--- /dev/null
+++ b/builtin-branch.c
@@ -0,0 +1,154 @@
+/*
+ * Builtin "git branch"
+ *
+ * Copyright (c) 2006 Kristian Høgsberg <krh@redhat.com>
+ * Based on git-branch.sh by Junio C Hamano.
+ */
+
+#include "cache.h"
+#include "refs.h"
+#include "commit.h"
+#include "builtin.h"
+
+static const char builtin_branch_usage[] =
+	"git-branch [(-d | -D) <branchname>] | [[-f] <branchname> [<start-point>]] | -r";
+
+
+static int remote_only = 0;
+static const char *head;
+static unsigned char head_sha1[20];
+
+static int find_sha1(struct commit *commit, void *data)
+{
+	return !memcmp(data, commit->object.sha1, sizeof commit->object.sha1);
+}
+
+static void delete_branches(int argc, const char **argv, int force)
+{
+	struct commit *rev1, *rev2;
+	unsigned char sha1[20];
+	const char *p, *name;
+	int i;
+
+	for (i = 0; i < argc; i++) {
+		if (!strcmp(head, argv[i]))
+			die("Cannot delete the branch you are currently on.");
+
+		name = git_path("refs/heads/%s", argv[i]);
+		p = resolve_ref(name, sha1, 1);
+		if (p == NULL)
+			die("Branch '%s' not found.", argv[i]);
+
+		rev1 = lookup_commit_reference(sha1);
+		rev2 = lookup_commit_reference(head_sha1);
+		if (!rev1 || !rev2)
+			die("Couldn't look up commit objects.");
+
+		/* This checks wether the merge bases of branch and
+		 * HEAD contains branch -- which means that the HEAD
+		 * contains everything in both.
+		 */
+
+		if (!force &&
+		    !for_each_merge_base(rev1, rev2, find_sha1, sha1)) {
+			fprintf(stderr,
+				"The branch '%s' is not a strict subset of your current HEAD.\n"
+				"If you are sure you want to delete it, run 'git branch -D %s'.\n",
+				argv[i], argv[i]);
+			exit(1);
+		}
+
+		unlink(name);
+		printf("Deleted branch %s.\n", argv[i]);
+	}
+}
+
+static int show_reference(const char *refname, const unsigned char *sha1)
+{
+	int is_head = !strcmp(refname, head);
+
+	printf("%c %s\n", (is_head ? '*' : ' '), refname);
+
+	return 0;
+}
+
+static void create_branch (const char *name, const char *start, int force)
+{
+	unsigned char sha1[20];
+	char ref[500];
+
+	snprintf (ref, sizeof ref, "heads/%s", name);
+	if (check_ref_format(ref))
+		die("'%s' is not a valid branch name.", name);
+
+	if (resolve_ref(git_path("refs/%s", ref), sha1, 1)) {
+		if (!force)
+			die("A branch named '%s' already exists.", name);
+		else if (!strcmp(head, name))
+			die("Cannot force update the current branch.");
+	}
+
+	if (get_sha1(start, sha1))
+		die("Not a valid branch point: '%s'", start);
+
+	if (write_ref_sha1_unlocked(ref, sha1))
+		die("Failed to create branch: %s.", strerror(errno));
+}
+
+int cmd_branch(int argc, const char **argv, char **envp)
+{
+	int delete = 0, force_delete = 0, force_create = 0;
+	int i, prefix_length;
+	const char *p;
+
+	setup_git_directory();
+	git_config(git_default_config);
+
+	for (i = 1; i < argc; i++) {
+		const char *arg = argv[i];
+
+		if (arg[0] != '-')
+			break;
+		if (!strcmp(arg, "--")) {
+			i++;
+			break;
+		}
+		if (!strcmp(arg, "-d")) {
+			delete = 1;
+			continue;
+		}
+		if (!strcmp(arg, "-D")) {
+			delete = 1;
+			force_delete = 1;
+			continue;
+		}
+		if (!strcmp(arg, "-f")) {
+			force_create = 1;
+			continue;
+		}
+		if (!strcmp(arg, "-r")) {
+			remote_only = 1;
+			continue;
+		}
+		die(builtin_branch_usage);
+	}
+
+	prefix_length = strlen(git_path("refs/heads/"));
+	p = resolve_ref(git_path("HEAD"), head_sha1, 0);
+	if (!p)
+		die("Failed to resolve HEAD as a valid ref");
+	head = strdup(p + prefix_length);
+
+	if (delete)
+		delete_branches(argc - i, argv + i, force_delete);
+	else if (i == argc && remote_only)
+		for_each_remote_ref(show_reference);
+	else if (i == argc)
+		for_each_branch_ref(show_reference);
+	else if (argc - i == 1)
+		create_branch (argv[i], head, force_create);
+	else
+		create_branch (argv[i], argv[i + 1], force_create);
+
+	return 0;
+}
diff --git a/builtin.h b/builtin.h
index 78275ea..0105358 100644
--- a/builtin.h
+++ b/builtin.h
@@ -28,5 +28,7 @@ extern int cmd_grep(int argc, const char
 extern int cmd_add(int argc, const char **argv, char **envp);
 extern int cmd_rev_list(int argc, const char **argv, char **envp);
 extern int cmd_check_ref_format(int argc, const char **argv, char **envp);
+extern int cmd_branch(int argc, const char **argv, char **envp);
+extern int cmd_merge_base(int argc, const char **argv, char **envp);
 
 #endif
diff --git a/commit.h b/commit.h
index 8d7514c..b1a518a 100644
--- a/commit.h
+++ b/commit.h
@@ -104,4 +104,9 @@ struct commit_graft *read_graft_line(cha
 int register_commit_graft(struct commit_graft *, int);
 int read_graft_file(const char *graft_file);
 
+/* merge-base.c */
+int for_each_merge_base(struct commit *rev1, struct commit *rev2,
+			int (*fn)(struct commit *commit, void *data),
+			void  *data);
+
 #endif /* COMMIT_H */
diff --git a/git-branch.sh b/git-branch.sh
deleted file mode 100755
index 134e68c..0000000
--- a/git-branch.sh
+++ /dev/null
@@ -1,120 +0,0 @@
-#!/bin/sh
-
-USAGE='[(-d | -D) <branchname>] | [[-f] <branchname> [<start-point>]] | -r'
-LONG_USAGE='If no arguments, show available branches and mark current branch with a star.
-If one argument, create a new branch <branchname> based off of current HEAD.
-If two arguments, create a new branch <branchname> based off of <start-point>.'
-
-SUBDIRECTORY_OK='Yes'
-. git-sh-setup
-
-headref=$(git-symbolic-ref HEAD | sed -e 's|^refs/heads/||')
-
-delete_branch () {
-    option="$1"
-    shift
-    for branch_name
-    do
-	case ",$headref," in
-	",$branch_name,")
-	    die "Cannot delete the branch you are on." ;;
-	,,)
-	    die "What branch are you on anyway?" ;;
-	esac
-	branch=$(cat "$GIT_DIR/refs/heads/$branch_name") &&
-	    branch=$(git-rev-parse --verify "$branch^0") ||
-		die "Seriously, what branch are you talking about?"
-	case "$option" in
-	-D)
-	    ;;
-	*)
-	    mbs=$(git-merge-base -a "$branch" HEAD | tr '\012' ' ')
-	    case " $mbs " in
-	    *' '$branch' '*)
-		# the merge base of branch and HEAD contains branch --
-		# which means that the HEAD contains everything in both.
-		;;
-	    *)
-		echo >&2 "The branch '$branch_name' is not a strict subset of your current HEAD.
-If you are sure you want to delete it, run 'git branch -D $branch_name'."
-		exit 1
-		;;
-	    esac
-	    ;;
-	esac
-	rm -f "$GIT_DIR/refs/heads/$branch_name"
-	echo "Deleted branch $branch_name."
-    done
-    exit 0
-}
-
-ls_remote_branches () {
-    git-rev-parse --symbolic --all |
-    sed -ne 's|^refs/\(remotes/\)|\1|p' |
-    sort
-}
-
-force=
-while case "$#,$1" in 0,*) break ;; *,-*) ;; *) break ;; esac
-do
-	case "$1" in
-	-d | -D)
-		delete_branch "$@"
-		exit
-		;;
-	-r)
-		ls_remote_branches
-		exit
-		;;
-	-f)
-		force="$1"
-		;;
-	--)
-		shift
-		break
-		;;
-	-*)
-		usage
-		;;
-	esac
-	shift
-done
-
-case "$#" in
-0)
-	git-rev-parse --symbolic --branches |
-	sort |
-	while read ref
-	do
-		if test "$headref" = "$ref"
-		then
-			pfx='*'
-		else
-			pfx=' '
-		fi
-		echo "$pfx $ref"
-	done
-	exit 0 ;;
-1)
-	head=HEAD ;;
-2)
-	head="$2^0" ;;
-esac
-branchname="$1"
-
-rev=$(git-rev-parse --verify "$head") || exit
-
-git-check-ref-format "heads/$branchname" ||
-	die "we do not like '$branchname' as a branch name."
-
-if [ -e "$GIT_DIR/refs/heads/$branchname" ]
-then
-	if test '' = "$force"
-	then
-		die "$branchname already exists."
-	elif test "$branchname" = "$headref"
-	then
-		die "cannot force-update the current branch."
-	fi
-fi
-git update-ref "refs/heads/$branchname" $rev
diff --git a/git.c b/git.c
index 7db5cc1..fb66c0e 100644
--- a/git.c
+++ b/git.c
@@ -53,7 +53,9 @@ static void handle_internal_command(int 
 		{ "grep", cmd_grep },
 		{ "add", cmd_add },
 		{ "rev-list", cmd_rev_list },
-		{ "check-ref-format", cmd_check_ref_format }
+		{ "check-ref-format", cmd_check_ref_format },
+		{ "branch", cmd_branch },
+		{ "merge-base", cmd_merge_base }
 	};
 	int i;
 
diff --git a/merge-base.c b/merge-base.c
index 4856ca0..0aa6ed4 100644
--- a/merge-base.c
+++ b/merge-base.c
@@ -1,6 +1,6 @@
-#include <stdlib.h>
 #include "cache.h"
 #include "commit.h"
+#include "builtin.h"
 
 #define PARENT1 1
 #define PARENT2 2
@@ -167,16 +167,16 @@ static void mark_reachable_commits(struc
 	}
 }
 
-static int merge_base(struct commit *rev1, struct commit *rev2)
+int for_each_merge_base(struct commit *rev1, struct commit *rev2,
+			int (*fn)(struct commit *commit, void *data),
+			void *data)
 {
 	struct commit_list *list = NULL;
 	struct commit_list *result = NULL;
 	struct commit_list *tmp = NULL;
 
-	if (rev1 == rev2) {
-		printf("%s\n", sha1_to_hex(rev1->object.sha1));
-		return 0;
-	}
+	if (rev1 == rev2) 
+		return fn(rev1, data);
 
 	parse_commit(rev1);
 	parse_commit(rev2);
@@ -220,12 +220,13 @@ static int merge_base(struct commit *rev
 
 	while (result) {
 		struct commit *commit = result->item;
+		int retval;
 		result = result->next;
 		if (commit->object.flags & UNINTERESTING)
 			continue;
-		printf("%s\n", sha1_to_hex(commit->object.sha1));
-		if (!show_all)
-			return 0;
+		retval = fn(commit, data);
+		if (retval)
+			return retval;
 		commit->object.flags |= UNINTERESTING;
 	}
 	return 0;
@@ -234,7 +235,13 @@ static int merge_base(struct commit *rev
 static const char merge_base_usage[] =
 "git-merge-base [--all] <commit-id> <commit-id>";
 
-int main(int argc, char **argv)
+static int print_merge_base(struct commit *commit, void *data)
+{
+	printf("%s\n", sha1_to_hex(commit->object.sha1));
+	return show_all ? 0 : 1;
+}
+
+int cmd_merge_base(int argc, const char **argv, char **envp)
 {
 	struct commit *rev1, *rev2;
 	unsigned char rev1key[20], rev2key[20];
@@ -243,7 +250,7 @@ int main(int argc, char **argv)
 	git_config(git_default_config);
 
 	while (1 < argc && argv[1][0] == '-') {
-		char *arg = argv[1];
+		const char *arg = argv[1];
 		if (!strcmp(arg, "-a") || !strcmp(arg, "--all"))
 			show_all = 1;
 		else
@@ -260,5 +267,8 @@ int main(int argc, char **argv)
 	rev2 = lookup_commit_reference(rev2key);
 	if (!rev1 || !rev2)
 		return 1;
-	return merge_base(rev1, rev2);
+
+	for_each_merge_base(rev1, rev2, print_merge_base, NULL);
+
+	return 0;
 }

^ permalink raw reply related

* [PATCH] check for error return from fork()
From: Paul T Darga @ 2006-06-08 18:14 UTC (permalink / raw)
  To: git

Trivial fixup for fork() callsites which do not check for errors.

Signed-off-by: Paul T Darga <pdarga@umich.edu>
---
 connect.c   |    2 ++
 imap-send.c |    6 +++++-
 rsh.c       |    6 +++++-
 3 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/connect.c b/connect.c
index eca94f7..52d709e 100644
--- a/connect.c
+++ b/connect.c
@@ -657,6 +657,8 @@ int git_connect(int fd[2], char *url, co
 	if (pipe(pipefd[0]) < 0 || pipe(pipefd[1]) < 0)
 		die("unable to create pipe pair for communication");
 	pid = fork();
+	if (pid < 0)
+		die("unable to fork");
 	if (!pid) {
 		snprintf(command, sizeof(command), "%s %s", prog,
 			 sq_quote(path));
diff --git a/imap-send.c b/imap-send.c
index 52e2400..285ad29 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -924,6 +924,7 @@ imap_open_store( imap_server_conf_t *srv
 	struct hostent *he;
 	struct sockaddr_in addr;
 	int s, a[2], preauth;
+	pid_t pid;
 
 	ctx = xcalloc( sizeof(*ctx), 1 );
 
@@ -941,7 +942,10 @@ imap_open_store( imap_server_conf_t *srv
 			exit( 1 );
 		}
 
-		if (fork() == 0) {
+		pid = fork();
+		if (pid < 0)
+			_exit( 127 );
+		if (!pid) {
 			if (dup2( a[0], 0 ) == -1 || dup2( a[0], 1 ) == -1)
 				_exit( 127 );
 			close( a[0] );
diff --git a/rsh.c b/rsh.c
index d665269..07166ad 100644
--- a/rsh.c
+++ b/rsh.c
@@ -48,6 +48,7 @@ int setup_connection(int *fd_in, int *fd
 	int sizen;
 	int of;
 	int i;
+	pid_t pid;
 
 	if (!strcmp(url, "-")) {
 		*fd_in = 0;
@@ -91,7 +92,10 @@ int setup_connection(int *fd_in, int *fd
 	if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv))
 		return error("Couldn't create socket");
 
-	if (!fork()) {
+	pid = fork();
+	if (pid < 0)
+		return error("Couldn't fork");
+	if (!pid) {
 		const char *ssh, *ssh_basename;
 		ssh = getenv("GIT_SSH");
 		if (!ssh) ssh = "ssh";
-- 
1.4.0.rc2


-- 
Paul T. Darga - pdarga@umich.edu - http://www.eecs.umich.edu/~pdarga/
"When I gave food to the poor, they called me a saint. When I asked
why the poor were hungry, they called me a communist."
    -- Dom Helder Camara, Brazilian Bishop, Nobel Peace Prize nominee

^ permalink raw reply related

* Re: [PATCH 0/2] Introduce ~/.gitconfig
From: Jakub Narebski @ 2006-06-08 18:32 UTC (permalink / raw)
  To: git
In-Reply-To: <1149775348.23938.236.camel@cashmere.sps.mot.com>

Jon Loeliger wrote:

> On Thu, 2006-06-08 at 06:30, Johannes Schindelin wrote:

>> - The --no-local flag [...]
> 
> Could we have multiple levels, and have names that call out
> where it applies?  Perhaps something like:
> 
> --repo   into $GIT_DIR/.gitconfig  <- current default, right?
> --home   into ~/.gitconfig
> --site   into /etc/gitconfig
> --share  into /usr/share/git/config

I like that too, wlthough --home might be named --user, and --share be named
--predefined or --library.

-- 
Jakub Narebski
Warsaw, Poland

^ permalink raw reply

* Re: [PATCH 2/2] repo-config: learn the flag "--no-local"
From: Jakub Narebski @ 2006-06-08 18:36 UTC (permalink / raw)
  To: git
In-Reply-To: <20060608153508.GB8047@satan.machinehead.org>

Aneesh Kumar K.V wrote:

> On Thu, Jun 08, 2006 at 03:37:47PM +0200, Karl Hasselstr?m wrote:
>> On 2006-06-08 13:41:04 +0200, Johannes Schindelin wrote:
>> 
>> My vote goes to --no-local, but only if we also get a --no-no-local
>> flag with the opposite meaning. Otherwise, I'd prefer --global. :-)
>> 
> 
> 
> I guess it makes much sense to rename the command to git-config and say 
> 
> git config  alias.l  -> for golbal config 
> git config --repo alias.l -> for repo specific config 

And legacy "git repo-config" as equivalent of "git config --repo", perhaps
implemented via alias mechanism (if there woul be system-wide coniguration
file, otherwise in skeleton/template).

-- 
Jakub Narebski
Warsaw, Poland

^ permalink raw reply

* Re: [PATCH] Implement git-branch and git-merge-base as built-ins.
From: Junio C Hamano @ 2006-06-08 18:53 UTC (permalink / raw)
  To: Kristian Høgsberg; +Cc: git
In-Reply-To: <4488633A.5060409@bitplanet.net>

Kristian Høgsberg <krh@bitplanet.net> writes:

> This patch is more or less a straight port of git-branch from shell
> script to C.  Branch deletion uses git-merge-base to check if it is safe
> to delete a branch, so I changed merge-base.c to export this functionality
> as a for_each_merge_base() iterator.  As a side effect, git-merge-base is
> now also a built-in command.

First, some lighter-weight comments:

 (0) Somehow your diff have two copies of everything.  How did
     you prepare this message I wonder...?

 (1) Sign your work, please.

 (2) I would have preferred a patch to do merge-base and another
     patch to do branch.  That way, we could do merge-base
     without doing branch if we wanted to.

But the patch is wrong.  Your for-each-merge-base cannot be
called more than once, but delete-branches does.

The merge-base program as implemented currently is written with
the assumption that it is called only once, and leaves its
working state in parsed commit objects all over the place.  In
order to make the second and subsequent call to work correctly,
you need to clean the flags up.

As a demonstration, with this function appended to your
merge-base.c and making it a built-in "merge-base-bogo":

int cmd_merge_base_bogo(int argc, const char **argv, char **envp)
{
	struct commit *rev1, *rev2;
	unsigned char rev1key[20], rev2key[20];
	int errors = 0;

	setup_git_directory();
	git_config(git_default_config);

	while (1 < argc && argv[1][0] == '-') {
		const char *arg = argv[1];
		if (!strcmp(arg, "-a") || !strcmp(arg, "--all"))
			show_all = 1;
		else
			usage(merge_base_usage);
		argc--; argv++;
	}
	for (; 3 <= argc; argc -= 2, argv += 2) {
		if (get_sha1(argv[1], rev1key) ||
		    !(rev1 = lookup_commit_reference(rev1key))) {
			error("Not a valid object name %s", argv[1]);
			errors++;
			continue;
		}
		if (get_sha1(argv[2], rev2key) ||
		    !(rev2 = lookup_commit_reference(rev2key))) {
			error("Not a valid object name %s", argv[2]);
			errors++;
			continue;
		}
		for_each_merge_base(rev1, rev2, print_merge_base, NULL);
	}
	if (1 < argc) {
		error("Trailing argument %s not used", argv[1]);
		errors++;
	}
	return !!errors;
}

Here is what happens.

: gitster; ./git merge-base-bogo 66ae0c77 ced9456a
262a6ef76a1dde97ab50d79fa5cd6d3f9f125765
: gitster; ./git merge-base-bogo 89719209 262a6ef7
aa6bf0eb6489d652c5877d65160ed33c857afa74
: gitster; ./git merge-base-bogo 66ae0c77 ced9456a 89719209 262a6ef7
262a6ef76a1dde97ab50d79fa5cd6d3f9f125765
262a6ef76a1dde97ab50d79fa5cd6d3f9f125765

This is because the invocation for the second pair does not
start with a clean slate, and is affected by the leftover states
from the computation for the first pair.  If you swap the
arguments, you sometimes get correct result by accident, like this:

: gitster; ./git merge-base-bogo 89719209 262a6ef7 66ae0c77 ced9456a
aa6bf0eb6489d652c5877d65160ed33c857afa74
262a6ef76a1dde97ab50d79fa5cd6d3f9f125765

Incidentally, this is why I haven't done "A...B" revision syntax
extension to mean "^$(git merge-base A B) B".

^ permalink raw reply

* Re: [PATCH 1/2]: amendment
From: Johannes Schindelin @ 2006-06-08 20:11 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7v7j3r8uab.fsf@assigned-by-dhcp.cox.net>

Hi,

On Thu, 8 Jun 2006, Junio C Hamano wrote:

> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> 
> > I completely forgot that with a global config, it makes sense to have 
> > aliases even if we are not in a git repository.
> >
> > So, in git.c, handle_alias() the "if (nongit)" makes no sense any longer. 
> > If I have to revise the patch anyway, I will include the change, but if 
> > you decide to take it, please change that.
> >
> > Ciao,
> > Dscho
> >
> > P.S.: There might be other users (such as git-peek-remote) who want that 
> > change, too.
> 
> Well, this is pretty late in the 1.4.0 game and honestly I am
> pretty reluctant to merge this in, push 1.4.0 out in 48 hours
> and leave for nearly a week.

Sorry, I timed that rather badly.

> My preference is to cook this in "next" for a while and merge it
> post 1.4.0.

Judging from the flurry of creative flag naming wishes, I think that will 
do just fine.

Ciao,
Dscho

^ permalink raw reply

* Re: [PATCH 0/2] Introduce ~/.gitconfig
From: Johannes Schindelin @ 2006-06-08 20:15 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git
In-Reply-To: <e69qev$nnl$1@sea.gmane.org>

Hi,

On Thu, 8 Jun 2006, Jakub Narebski wrote:

> Jon Loeliger wrote:
> 
> > On Thu, 2006-06-08 at 06:30, Johannes Schindelin wrote:
> 
> >> - The --no-local flag [...]
> > 
> > Could we have multiple levels, and have names that call out
> > where it applies?  Perhaps something like:
> > 
> > --repo   into $GIT_DIR/.gitconfig  <- current default, right?
> > --home   into ~/.gitconfig
> > --site   into /etc/gitconfig
> > --share  into /usr/share/git/config
> 
> I like that too, wlthough --home might be named --user, and --share be 
> named --predefined or --library.

I am rather disinclined for the --share or --predefined flags, as these 
would only make sense for the administrator. And since this code was 
partly written by me, it eats small children.

Ciao,
Dscho

^ permalink raw reply

* Re: [PATCH 2/2] repo-config: learn the flag "--no-local"
From: Johannes Schindelin @ 2006-06-08 20:17 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git
In-Reply-To: <e69qne$nnl$2@sea.gmane.org>

Hi,

On Thu, 8 Jun 2006, Jakub Narebski wrote:

> And legacy "git repo-config" as equivalent of "git config --repo", perhaps
> implemented via alias mechanism (if there woul be system-wide coniguration
> file, otherwise in skeleton/template).

Why use the alias mechanism? I, for one, never install git. So, this 
solution is rather fragile. But there are better ways: the builtin 
mechanism for one.

Ciao,
Dscho

^ permalink raw reply

* Re: [PATCH 2/2] repo-config: learn the flag "--no-local"
From: Johannes Schindelin @ 2006-06-08 20:18 UTC (permalink / raw)
  To: Aneesh Kumar K.V; +Cc: junkio, git
In-Reply-To: <20060608153236.GA8047@satan.machinehead.org>

Hi,

On Thu, 8 Jun 2006, Aneesh Kumar K.V wrote:

> On Thu, Jun 08, 2006 at 01:31:46PM +0200, Johannes Schindelin wrote:
> > 
> > Since there is a global config now, we need a way to access it
> > conveniently. Now you can say
> > 
> > 	git repo-config --no-local alias.l "log --stat -M ORIG_HEAD.."
> > 
> > to set the alias globally (it will be stored in ~/.gitconfig).
> > 
> 
> how about  making the above 
> 
>    git config --repo alias.l "log --stat -M ORIG_HEAD.."

IMHO it would be a sane thing to make this default. Most config variables 
are repository dependent.

Ciao,
Dscho

^ permalink raw reply

* Re: [PATCH 2/2] repo-config: learn the flag "--no-local"
From: Johannes Schindelin @ 2006-06-08 20:24 UTC (permalink / raw)
  To: Sean; +Cc: Junio C Hamano, lukass, git
In-Reply-To: <BAYC1-PASMTP04DDBAA584B31A4B0F31DCAE8B0@CEZ.ICE>

Hi,

On Thu, 8 Jun 2006, Sean wrote:

> On Thu, 08 Jun 2006 09:25:53 -0700
> Junio C Hamano <junkio@cox.net> wrote:
> 
> 
> > The wording "--no-local" means you are looking at things
> > relative to a particular repository.  I.e. some configuration
> > variables come from repository-local file, and others from
> > somewhere else.  But I do not think that somewhere else is
> > "global".  We are reading from $HOME, which is different
> > depending on who is interacting with that same repository.  So I
> > would probably call the other one "--user" or something if I
> > were force to pick name.
> 
> --user or --home makes a lot of sense.  Alternatively you could
> just be explicit: --config=~ or --config=/etc/gitconfig where
> /.gitconfig is automatically appended to the path if it ends in
> a directory name.

I think --user makes more sense than --home, since it does not matter 
_where_ it is stored, but _when_ it is retreived.

In the same vein, I do not think it is user friendly to expect the user to 
remember if it was .gitconfig, .git or .gitrc.

Ciao,
Dscho

^ permalink raw reply

* Re: [PATCH 2/2] repo-config: learn the flag "--no-local"
From: Sean @ 2006-06-08 20:30 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: junkio, lukass, git
In-Reply-To: <Pine.LNX.4.63.0606082222470.28323@wbgn013.biozentrum.uni-wuerzburg.de>

On Thu, 8 Jun 2006 22:24:31 +0200 (CEST)
Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:

> I think --user makes more sense than --home, since it does not matter 
> _where_ it is stored, but _when_ it is retreived.

--home seems more natural to me for some reason but I don't feel strongly
about it.
 
> In the same vein, I do not think it is user friendly to expect the user to 
> remember if it was .gitconfig, .git or .gitrc.

Sure, was just thinking that this could be used by an administrator to
modify _other_ users' configs.. but probably not worth it.

Cheers,
Sean

^ permalink raw reply

* Re: [PATCH 2/2] repo-config: learn the flag "--no-local"
From: Johannes Schindelin @ 2006-06-08 20:42 UTC (permalink / raw)
  To: Sean; +Cc: junkio, lukass, git
In-Reply-To: <BAYC1-PASMTP102B1021B943F57F9FB1EEAE8B0@CEZ.ICE>

Hi,

On Thu, 8 Jun 2006, Sean wrote:

> On Thu, 8 Jun 2006 22:24:31 +0200 (CEST)
> Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> 
> > I think --user makes more sense than --home, since it does not matter 
> > _where_ it is stored, but _when_ it is retreived.
> 
> --home seems more natural to me for some reason but I don't feel strongly
> about it.

I'd like to know how --home tells you when this key is retreived.

> > In the same vein, I do not think it is user friendly to expect the user to 
> > remember if it was .gitconfig, .git or .gitrc.
> 
> Sure, was just thinking that this could be used by an administrator to
> modify _other_ users' configs.. but probably not worth it.

The admin has no business messing around with the users' configuration. 
And if she absolutely wants to be a BOFH, she can fire up any editor, or 
copy .gitconfig to /root/.gitconfig, use git-config, and copy it back, or 
do what she does all the time: "su <user>". But frankly, we should not 
support a bad work flow.

BTW it is the same reason I would rather not see /etc/gitconfig: it 
meddles with an existing configuration. If you want to give defaults, you 
can use a skeleton for $HOME, and templates for $GIT_DIR. As a user, I 
would be very surprised if the behaviour of git changed from one day to 
the other without my changing anything.

Ciao,
Dscho

^ permalink raw reply

* Re: [PATCH 2/2] repo-config: learn the flag "--no-local"
From: Jakub Narebski @ 2006-06-08 20:55 UTC (permalink / raw)
  To: git
In-Reply-To: <Pine.LNX.4.63.0606082235020.28405@wbgn013.biozentrum.uni-wuerzburg.de>

Johannes Schindelin wrote:

> BTW it is the same reason I would rather not see /etc/gitconfig: it 
> meddles with an existing configuration. If you want to give defaults, you 
> can use a skeleton for $HOME, and templates for $GIT_DIR. As a user, I 
> would be very surprised if the behaviour of git changed from one day to 
> the other without my changing anything.

I agree wholeheartily. I guess that the 'skeleton' part has yet to be
written...

-- 
Jakub Narebski
Warsaw, Poland

^ permalink raw reply

* Re: [PATCH 2/2] repo-config: learn the flag "--no-local"
From: Sean @ 2006-06-08 20:55 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: junkio, lukass, git
In-Reply-To: <Pine.LNX.4.63.0606082235020.28405@wbgn013.biozentrum.uni-wuerzburg.de>

On Thu, 8 Jun 2006 22:42:17 +0200 (CEST)
Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:

> I'd like to know how --home tells you when this key is retreived.

I honestly don't know.  How does --user tell you when this key is retrieved?

> The admin has no business messing around with the users' configuration. 
> And if she absolutely wants to be a BOFH, she can fire up any editor, or 
> copy .gitconfig to /root/.gitconfig, use git-config, and copy it back, or 
> do what she does all the time: "su <user>". But frankly, we should not 
> support a bad work flow.
> 
> BTW it is the same reason I would rather not see /etc/gitconfig: it 
> meddles with an existing configuration. If you want to give defaults, you 
> can use a skeleton for $HOME, and templates for $GIT_DIR. As a user, I 
> would be very surprised if the behaviour of git changed from one day to 
> the other without my changing anything.

This seems like a rather heavy handed policy for an application to enforce.
To my mind, these types of decisions are best left up to administrators; 
obviously we can't guess all the creative ways git will be used beforehand.

Sean

^ permalink raw reply

* Re: [PATCH 2/2] repo-config: learn the flag "--no-local"
From: Johannes Schindelin @ 2006-06-08 21:03 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git
In-Reply-To: <e6a2rt$n6p$1@sea.gmane.org>

Hi,

On Thu, 8 Jun 2006, Jakub Narebski wrote:

> Johannes Schindelin wrote:
> 
> > BTW it is the same reason I would rather not see /etc/gitconfig: it 
> > meddles with an existing configuration. If you want to give defaults, you 
> > can use a skeleton for $HOME, and templates for $GIT_DIR. As a user, I 
> > would be very surprised if the behaviour of git changed from one day to 
> > the other without my changing anything.
> 
> I agree wholeheartily. I guess that the 'skeleton' part has yet to be
> written...

I don't know what exactly you mean: the skeleton copying part, or the 
default .gitconfig?

As for the skeleton copying part, on the machine I am writing this on, 
there is a /etc/skel/ directory, which is automatically copied to the 
$HOME of every newly created user.

As for the default .gitconfig (which you could put into /etc/skel/): if 
the default behaviour of git is not to your liking, just make a 
$HOME/.gitconfig, and once you are satisfied with it, stick a copy into 
/etc/skel!

Ciao,
Dscho

^ permalink raw reply

* Re: [PATCH 2/2] repo-config: learn the flag "--no-local"
From: Johannes Schindelin @ 2006-06-08 21:10 UTC (permalink / raw)
  To: Sean; +Cc: junkio, lukass, git
In-Reply-To: <BAYC1-PASMTP040660E676E00AD1631524AE8B0@CEZ.ICE>

Hi,

On Thu, 8 Jun 2006, Sean wrote:

> On Thu, 8 Jun 2006 22:42:17 +0200 (CEST)
> Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> 
> > I'd like to know how --home tells you when this key is retreived.
> 
> I honestly don't know.  How does --user tell you when this key is 
> retrieved?

If I have --user vs. --repo, then I expect the setting to be active for 
the user vs. the repository, respectively.

> > The admin has no business messing around with the users' configuration. 
> > And if she absolutely wants to be a BOFH, she can fire up any editor, or 
> > copy .gitconfig to /root/.gitconfig, use git-config, and copy it back, or 
> > do what she does all the time: "su <user>". But frankly, we should not 
> > support a bad work flow.
> > 
> > BTW it is the same reason I would rather not see /etc/gitconfig: it 
> > meddles with an existing configuration. If you want to give defaults, you 
> > can use a skeleton for $HOME, and templates for $GIT_DIR. As a user, I 
> > would be very surprised if the behaviour of git changed from one day to 
> > the other without my changing anything.
> 
> This seems like a rather heavy handed policy for an application to enforce.
> To my mind, these types of decisions are best left up to administrators; 

Clearly, you have not met the same administrators as I did.

> obviously we can't guess all the creative ways git will be used beforehand.

That is right, but is it for somebody else to decide the creative way, or 
for you?

Ciao,
Dscho

^ permalink raw reply

* Re: [PATCH 2/2] repo-config: learn the flag "--no-local"
From: Jakub Narebski @ 2006-06-08 21:15 UTC (permalink / raw)
  To: git
In-Reply-To: <Pine.LNX.4.63.0606082300390.28654@wbgn013.biozentrum.uni-wuerzburg.de>

Johannes Schindelin wrote:

> Hi,
> 
> On Thu, 8 Jun 2006, Jakub Narebski wrote:
> 
>> Johannes Schindelin wrote:
>> 
>> > BTW it is the same reason I would rather not see /etc/gitconfig: it 
>> > meddles with an existing configuration. If you want to give defaults,
you 
>> > can use a skeleton for $HOME, and templates for $GIT_DIR. As a user, I 
>> > would be very surprised if the behaviour of git changed from one day to 
>> > the other without my changing anything.
>> 
>> I agree wholeheartily. I guess that the 'skeleton' part has yet to be
>> written...
> 
> I don't know what exactly you mean: the skeleton copying part, or the 
> default .gitconfig?

No, I mean the default skeleton for .gitconfig/.gitrc in git distribution or
git deb/rpm, and install copying it to appropriate drectory (/etc/skel/ if
installed as root, or $HOME if installed as an ordinary user).

-- 
Jakub Narebski
Warsaw, Poland

^ permalink raw reply

* Re: [PATCH 2/2] repo-config: learn the flag "--no-local"
From: Sean @ 2006-06-08 21:23 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: junkio, lukass, git
In-Reply-To: <Pine.LNX.4.63.0606082308010.28722@wbgn013.biozentrum.uni-wuerzburg.de>

On Thu, 8 Jun 2006 23:10:15 +0200 (CEST)
Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:

> If I have --user vs. --repo, then I expect the setting to be active for 
> the user vs. the repository, respectively.

*shrug*  This seems exactly the same for --home; like I said I don't
care enough to argue about it though.

> Clearly, you have not met the same administrators as I did.

Maybe not.
 
> > obviously we can't guess all the creative ways git will be used beforehand.
> 
> That is right, but is it for somebody else to decide the creative way, or 
> for you?

My argument was that we should not build in policies that assume administrators
are incompetent.  That we should put the tools in their hands and not restrict
them.  That lets them be as creative as they want and not constrained because
we have a preexisting opinion about their abilities or an opinion about the
policies they should follow with regard to their users files etc.

Anyway, i'm bowing out of this discussion because i'm sure you'll decide
a reasonable course of action.

Cheers,
Sean

^ permalink raw reply

* [PATCH] git-rm: fix possible segfault
From: SungHyun Nam @ 2006-06-09  2:10 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git


Signed-off-by: SungHyun Nam <goweol@gmail.com>

---
 builtin-rm.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/builtin-rm.c b/builtin-rm.c
index ef2f8b5..aeda415 100644
--- a/builtin-rm.c
+++ b/builtin-rm.c
@@ -83,6 +83,9 @@ int cmd_rm(int argc, const char **argv, 
 		}
 		die(builtin_rm_usage);
 	}
+	if (i >= argc)
+		usage(builtin_rm_usage);
+
 	pathspec = get_pathspec(prefix, argv + i);
 
 	seen = NULL;
-- 
1.4.0.rc1.gfd7e

^ 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