Git development
 help / color / mirror / Atom feed
* Re: rebase, file permissions and removed file
From: Pascal Obry @ 2008-10-27 17:12 UTC (permalink / raw)
  To: Samuel Tardieu; +Cc: Johannes Sixt, Git Mailing List
In-Reply-To: <2008-10-27-17-39-43+trackit+sam@rfc1149.net>

Samuel Tardieu a écrit :
> Why do you do a "rebase" in this case rather than a merge? Doesn't it
> make little sense to record a permission change on a *deleted* file?

Because this is in the context of git-svn, and I really want to rebase
my work before pushing it back to the Subversion repository.

-- 

--|------------------------------------------------------
--| Pascal Obry                           Team-Ada Member
--| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE
--|------------------------------------------------------
--|              http://www.obry.net
--| "The best way to travel is by means of imagination"
--|
--| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595

^ permalink raw reply

* Re: [VOTE] git versus mercurial (for DragonflyBSD)
From: Jakub Narebski @ 2008-10-27 18:01 UTC (permalink / raw)
  To: Arne Babenhauserheide; +Cc: git, mercurial, SLONIK.AZ
In-Reply-To: <200810271512.26352.arne_bab@web.de>

On Mon, 27 Oct 2008, Arne Babenhauserheide wrote:
> Am Monday 27 October 2008 13:48:38 schrieben Sie:

>>> All in all it's a UI issue - while the git UI bit me quite often, the
>>> Mercurial UI just works.
>>
>> But _that_ might be because you are used to Mercurial UI, isn't it?
> 
> I rather think it is because I was used the Subversion UI before I tried git 
> and Mercurial.

I think Mercurial UI is more compatibile with Subversion UI than Git;
additionally Mercurial uses separate, different names to avoid
ambiguities: examples are 'hg rollback' and 'hg backout' for commands
which various SCM name reset and revert, sometimes referring to one
and sometimes to the other.

AFAIK Git mostly follows BitKeeper UI; it is quite natural as it was
meant as replacement for BitKeeper for Linux kernel development.

[...]
> Also, Mercurial is Python based with quite readable code and it's very easy to 
> create extensions for new uses, when I need them. 
> 
> If you know Python, creating a new Mercurial extension isn't harder than 
> creating a shell chain command for git, but it feels much cleaner and is 
> nicely integrated once it's done. You can even change the operation of basic 
> commands very easily without having to touch any existing code. 

There are advantages and disadvantages to each method.

Git was developed in true Unix tools style, as described in TAOUP i.e. 
"The Art of UNIX Programming" by ESR (http://catb.org/esr/writings/taoup/html/)
In "Programming Pearls" by Jon Bentley there is in one of chapters
description of prototyping 'spell' using ready UNIX tools, pipelines,
and a few of custom tools, to examine the needs of 'spell'.

One of the consequences of this type of design is that there isn't
(yet?) something like git library; this is caused by the fact that
tools (plumbing) that make up git are designed to run once, and let
operating system take care of freeing resources.

On the other hand clean and clear design of git repository made it
possible to create native Git (re)implementation in Java: the JGit
project. (Well, Git is GPLv2 and JGit/Egit is BSD 3-clause/EPL, so
reimplementation might have been needed for licensing purposes anyway.
Well, it is not _full_ implementation yet...

Besides is writing plugin in Python for Mercurial that much easier
than writing new command or stuff in C for Git? Well, perhaps it is,
as only recently there began to appear API documentation, and there
were created utility mini-libraries like strbuf, or string_list,
or parseopt.

Also often third-party projects or stuff in contrib gets incorporated
into git proper; sometimes stuff is moved from git core to contrib,
if there is no maintainer however (git-svnimport, git-p4import).
Git repository has many roots: one from git core, one with gitk 
(graphical history viewer), one from what was git mail tools, one
with gitweb (web interface), and one with git-gui (graphical commit
tool).


The extending via plugins idea used by Mercurial, so succesfull IMHO
for Firefox, and I think quite successfull for ikiwiki for example, is
not without drawbacks, especially that there is no plugins clearinghouse,
and plugins are required for what is considered pretty required 
functionality, like bisect before hg 1.0.

See also blog post on vcscompare: "Plugins In Version Control"
http://vcscompare.blogspot.com/2008/06/plugins-in-version-cotnrol.html

-- 
Jakub Narebski
Poland

^ permalink raw reply

* Re: Terminology question: "tracking" branches
From: Johannes Schindelin @ 2008-10-27 18:44 UTC (permalink / raw)
  To: Marc Branchaud
  Cc: Michael J Gruber, Björn Steinbrink, Peter Harris, git,
	Junio C Hamano
In-Reply-To: <4905E1B0.8040601@xiplink.com>

Hi,

On Mon, 27 Oct 2008, Marc Branchaud wrote:

> Michael J Gruber wrote:
> > 
> > [adjective to be found] branch: A local branch which is set up to pull 
> > or rebase automatically from a tracking branch. Used for local 
> > modifications to remote branches. [I'm tempted to use local tracking 
> > branch here, but that would just add to the confusion.]
> 
> I say there's no need for an adjective here, as this is just a plain old
> branch that git-branch creates by default (right?).

I agree; I do not think that you need an adjective here.

I'd also recommend thinking about the branches as "local" and "remote".  
Not anything with "tracking" or "trailing" or somesuch.  When you really 
look at it from the non-technical view point, even the branches you have 
in refs/remotes/*/ are the remote branches; the fact that you have a local 
cached version of them is just a minor implementation detail.

And as to the "--track" thing?  I'd not make that big a deal out of it.  
At most, I'd say that a certain local branch happens to follow a certain 
remote branch, but that can change over time, right?  (Just change 
branch.<name>.merge...)

Ciao,
Dscho

^ permalink raw reply

* problems with clone and .gitattributes
From: Leo Razoumov @ 2008-10-27 18:46 UTC (permalink / raw)
  To: git

Hi Everyone,
I am using .gitattributes with clean/smudge filters to optimize
storage of OpenOffice binary files (zip compressed). So far it works
fine except for clone operation.
Apparently, "git clone" does not call smudge filter when checking out a branch.
I have to manually remove openoffice files and then do "git co -f" to
re-checkout them  again, this time smudge filter gets applied.

There is a little catch-22 problem here. .gitattributes are stored
in-tree and git clone does not know about these files existence until
it checks the tree out, by that time it is already too late to apply
filters.

Of course, there could be several obvious workarounds:

(1) git clone can redo checkout when it finds files affected by gitattributes

(2) before doing checkout "git clone" inspects tree-object and looks
for .gitattributes files. If found it checks them out first before all
other files. Now it can apply the attributes found as the checkout
process progresses.

IMHO, both workarounds are somewhat clumsy.
Is there anything cleaner that can be done to solve the problem?

--Leo--

^ permalink raw reply

* Re: [RFC PATCH] detection of directory renames
From: Yann Dirson @ 2008-10-27 19:13 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git
In-Reply-To: <m3fxmignz3.fsf@localhost.localdomain>

On Mon, Oct 27, 2008 at 06:35:44AM -0700, Jakub Narebski wrote:
> Yann Dirson <ydirson@altern.org> writes:
> 
> > This is a first very preliminar patch, mostly so people can comment
> > early on the big picture.  It has a number of limitations, many but
> > not all already listed as FIXME's in the patch itself.  If anything in
> > this patch seems so wrong it is not worth polishing it, it's the
> > perfect time to say so :)
> 
> What happened to this work? I din't see it mentioned in "what's
> cooking..." announcements...

I'm slowly bugfixing it, and plan to post a slightly updated version
soon.

^ permalink raw reply

* Re: Can't merge
From: Rémi Vanicat @ 2008-10-27 19:14 UTC (permalink / raw)
  To: html-kurs; +Cc: git
In-Reply-To: <20081027165247.141110@gmx.net>

html-kurs@gmx.de writes:

> Hi,
>
> I've run in trouble when trying to merge a branch:
> I've got a branch "foo".
> I checkout master.
>> git diff foo 
> shows many diffs.
> But 
>> git merge foo
> says:
> Already up-to-date.
>
> I'm using version 1.6.0.2
>
> Any idea what I'm doing wrong?

When git say "Already up-to-date" it tell you that all change introduced
in the foo branch are in master. But there could be change in master
that are not in foo, making foo and master different. You could try 

> gitk foo..master
to see commit that are in master but not in foo and that could introduce
the difference between the foo and master branch.


-- 
Rémi Vanicat

^ permalink raw reply

* Some hooks turned on by default in FreeBSD 4
From: Robert Boone @ 2008-10-27 19:14 UTC (permalink / raw)
  To: git

This was a fresh install from the git repository using the master branch
git version: 1.6.0.3.523.g304d0


Is this something that can be fixed with a recompile and different arguments?


[root@user /usr/local/cpanel.git]# git commit
fatal: exec .git/hooks/pre-commit failed.
[root@user /usr/local/cpanel.git]# ls -l .git/hooks/
total 52
-rw-r--r--  1 root  wheel   441 Oct 27 10:14 applypatch-msg
-rwxr-xr-x  1 root  wheel   452 Oct 27 10:14 applypatch-msg.sample
-rw-r--r--  1 root  wheel   887 Oct 27 10:14 commit-msg
-rwxr-xr-x  1 root  wheel   894 Oct 27 10:14 commit-msg.sample
-rw-r--r--  1 root  wheel   152 Oct 27 10:14 post-commit
-rwxr-xr-x  1 root  wheel   160 Oct 27 10:14 post-commit.sample
-rw-r--r--  1 root  wheel   510 Oct 27 10:14 post-receive
-rwxr-xr-x  1 root  wheel   553 Oct 27 10:14 post-receive.sample
-rw-r--r--  1 root  wheel   207 Oct 27 10:14 post-update
-rwxr-xr-x  1 root  wheel   189 Oct 27 10:14 post-update.sample
-rw-r--r--  1 root  wheel   387 Oct 27 10:14 pre-applypatch
-rwxr-xr-x  1 root  wheel   398 Oct 27 10:14 pre-applypatch.sample
-rw-r--r--  1 root  wheel  1706 Oct 27 10:14 pre-commit
-rwxr-xr-x  1 root  wheel   519 Oct 27 10:14 pre-commit.sample
-rw-r--r--  1 root  wheel  4262 Oct 27 10:14 pre-rebase
-rwxr-xr-x  1 root  wheel  4942 Oct 27 10:14 pre-rebase.sample
-rw-r--r--  1 root  wheel  1196 Oct 27 10:14 prepare-commit-msg
-rwxr-xr-x  1 root  wheel  1219 Oct 27 10:14 prepare-commit-msg.sample
-rw-r--r--  1 root  wheel  2910 Oct 27 10:14 update
-rwxr-xr-x  1 root  wheel  2892 Oct 27 10:14 update.sample

^ permalink raw reply

* Re: Some hooks turned on by default in FreeBSD 4
From: Pieter de Bie @ 2008-10-27 19:23 UTC (permalink / raw)
  To: Robert Boone, Git Mailinglist
In-Reply-To: <435624390810271214s16b964cbo131772ea4a760ef7@mail.gmail.com>


On 27 okt 2008, at 20:14, Robert Boone wrote:

> [root@user /usr/local/cpanel.git]# ls -l .git/hooks/
> total 52
> -rw-r--r--  1 root  wheel   441 Oct 27 10:14 applypatch-msg
> -rwxr-xr-x  1 root  wheel   452 Oct 27 10:14 applypatch-msg.sample

You probably installed the new git over an older one? The old files in  
the templates weren't deleted, so now you have both the old version  
without .sample and the new ones in your template folder.

^ permalink raw reply

* [PATCH 1/3] Disallow git branch -m for symrefs.
From: Miklos Vajna @ 2008-10-27 19:50 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Jeff King, Brandon Casey, git
In-Reply-To: <cover.1225136865.git.vmiklos@frugalware.org>

This had two problems with symrefs. First, it copied the actual sha1
instead of the "pointer", second it failed to remove the old ref after a
successful rename.

Given that till now delete_ref() always dereferenced symrefs, a new
parameters has been introduced to delete_ref() to allow deleting refs
without a dereference.

For now, we just don't allow renaming symref as no real-word workflow
needs it and doing so would be just an accent.

Signed-off-by: Miklos Vajna <vmiklos@frugalware.org>
---
 builtin-branch.c       |    2 +-
 builtin-receive-pack.c |    2 +-
 builtin-remote.c       |    4 ++--
 builtin-reset.c        |    2 +-
 builtin-send-pack.c    |    2 +-
 builtin-tag.c          |    2 +-
 builtin-update-ref.c   |    2 +-
 cache.h                |    2 +-
 refs.c                 |   33 +++++++++++++++++++++++----------
 t/t3200-branch.sh      |    9 +++++++++
 10 files changed, 41 insertions(+), 19 deletions(-)

diff --git a/builtin-branch.c b/builtin-branch.c
index 8d634ff..2b3613f 100644
--- a/builtin-branch.c
+++ b/builtin-branch.c
@@ -160,7 +160,7 @@ static int delete_branches(int argc, const char **argv, int force, int kinds)
 			continue;
 		}
 
-		if (delete_ref(name, sha1)) {
+		if (delete_ref(name, sha1, 0)) {
 			error("Error deleting %sbranch '%s'", remote,
 			       argv[i]);
 			ret = 1;
diff --git a/builtin-receive-pack.c b/builtin-receive-pack.c
index 45e3cd9..ab5fa1c 100644
--- a/builtin-receive-pack.c
+++ b/builtin-receive-pack.c
@@ -224,7 +224,7 @@ static const char *update(struct command *cmd)
 			warning ("Allowing deletion of corrupt ref.");
 			old_sha1 = NULL;
 		}
-		if (delete_ref(name, old_sha1)) {
+		if (delete_ref(name, old_sha1, 0)) {
 			error("failed to delete %s", name);
 			return "failed to delete";
 		}
diff --git a/builtin-remote.c b/builtin-remote.c
index df2be06..e396a3a 100644
--- a/builtin-remote.c
+++ b/builtin-remote.c
@@ -337,7 +337,7 @@ static int remove_branches(struct string_list *branches)
 		const char *refname = item->string;
 		unsigned char *sha1 = item->util;
 
-		if (delete_ref(refname, sha1))
+		if (delete_ref(refname, sha1, 0))
 			result |= error("Could not remove branch %s", refname);
 	}
 	return result;
@@ -565,7 +565,7 @@ static int prune(int argc, const char **argv)
 			const char *refname = states.stale.items[i].util;
 
 			if (!dry_run)
-				result |= delete_ref(refname, NULL);
+				result |= delete_ref(refname, NULL, 0);
 
 			printf(" * [%s] %s\n", dry_run ? "would prune" : "pruned",
 			       abbrev_ref(refname, "refs/remotes/"));
diff --git a/builtin-reset.c b/builtin-reset.c
index 16e6bb2..9514b77 100644
--- a/builtin-reset.c
+++ b/builtin-reset.c
@@ -279,7 +279,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
 		update_ref(msg, "ORIG_HEAD", orig, old_orig, 0, MSG_ON_ERR);
 	}
 	else if (old_orig)
-		delete_ref("ORIG_HEAD", old_orig);
+		delete_ref("ORIG_HEAD", old_orig, 0);
 	prepend_reflog_action("updating HEAD", msg, sizeof(msg));
 	update_ref_status = update_ref(msg, "HEAD", sha1, orig, 0, MSG_ON_ERR);
 
diff --git a/builtin-send-pack.c b/builtin-send-pack.c
index 910db92..bbf6e0a 100644
--- a/builtin-send-pack.c
+++ b/builtin-send-pack.c
@@ -234,7 +234,7 @@ static void update_tracking_ref(struct remote *remote, struct ref *ref)
 		if (args.verbose)
 			fprintf(stderr, "updating local tracking ref '%s'\n", rs.dst);
 		if (ref->deletion) {
-			delete_ref(rs.dst, NULL);
+			delete_ref(rs.dst, NULL, 0);
 		} else
 			update_ref("update by push", rs.dst,
 					ref->new_sha1, NULL, 0, 0);
diff --git a/builtin-tag.c b/builtin-tag.c
index b13fa34..1ff7b37 100644
--- a/builtin-tag.c
+++ b/builtin-tag.c
@@ -125,7 +125,7 @@ static int for_each_tag_name(const char **argv, each_tag_name_fn fn)
 static int delete_tag(const char *name, const char *ref,
 				const unsigned char *sha1)
 {
-	if (delete_ref(ref, sha1))
+	if (delete_ref(ref, sha1, 0))
 		return 1;
 	printf("Deleted tag '%s'\n", name);
 	return 0;
diff --git a/builtin-update-ref.c b/builtin-update-ref.c
index 56a0b1b..d8f3142 100644
--- a/builtin-update-ref.c
+++ b/builtin-update-ref.c
@@ -48,7 +48,7 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix)
 		die("%s: not a valid old SHA1", oldval);
 
 	if (delete)
-		return delete_ref(refname, oldval ? oldsha1 : NULL);
+		return delete_ref(refname, oldval ? oldsha1 : NULL, 0);
 	else
 		return update_ref(msg, refname, sha1, oldval ? oldsha1 : NULL,
 				  no_deref ? REF_NODEREF : 0, DIE_ON_ERR);
diff --git a/cache.h b/cache.h
index b0edbf9..a3c77f0 100644
--- a/cache.h
+++ b/cache.h
@@ -434,7 +434,7 @@ extern int commit_locked_index(struct lock_file *);
 extern void set_alternate_index_output(const char *);
 extern int close_lock_file(struct lock_file *);
 extern void rollback_lock_file(struct lock_file *);
-extern int delete_ref(const char *, const unsigned char *sha1);
+extern int delete_ref(const char *, const unsigned char *sha1, int delopt);
 
 /* Environment bits from configuration mechanism */
 extern int trust_executable_bit;
diff --git a/refs.c b/refs.c
index 0a126fa..31a2057 100644
--- a/refs.c
+++ b/refs.c
@@ -921,25 +921,33 @@ static int repack_without_ref(const char *refname)
 	return commit_lock_file(&packlock);
 }
 
-int delete_ref(const char *refname, const unsigned char *sha1)
+int delete_ref(const char *refname, const unsigned char *sha1, int delopt)
 {
 	struct ref_lock *lock;
-	int err, i, ret = 0, flag = 0;
+	int err, i = 0, ret = 0, flag = 0;
 
 	lock = lock_ref_sha1_basic(refname, sha1, 0, &flag);
 	if (!lock)
 		return 1;
 	if (!(flag & REF_ISPACKED)) {
 		/* loose */
-		i = strlen(lock->lk->filename) - 5; /* .lock */
-		lock->lk->filename[i] = 0;
-		err = unlink(lock->lk->filename);
+		const char *path;
+
+		if (!(delopt & REF_NODEREF)) {
+			i = strlen(lock->lk->filename) - 5; /* .lock */
+			lock->lk->filename[i] = 0;
+			path = lock->lk->filename;
+		} else {
+			path = git_path(refname);
+		}
+		err = unlink(path);
 		if (err && errno != ENOENT) {
 			ret = 1;
 			error("unlink(%s) failed: %s",
-			      lock->lk->filename, strerror(errno));
+			      path, strerror(errno));
 		}
-		lock->lk->filename[i] = '.';
+		if (!(delopt & REF_NODEREF))
+			lock->lk->filename[i] = '.';
 	}
 	/* removing the loose one could have resurrected an earlier
 	 * packed one.  Also, if it was not loose we need to repack
@@ -964,11 +972,16 @@ int rename_ref(const char *oldref, const char *newref, const char *logmsg)
 	struct ref_lock *lock;
 	struct stat loginfo;
 	int log = !lstat(git_path("logs/%s", oldref), &loginfo);
+	const char *symref = NULL;
 
 	if (S_ISLNK(loginfo.st_mode))
 		return error("reflog for %s is a symlink", oldref);
 
-	if (!resolve_ref(oldref, orig_sha1, 1, &flag))
+	symref = resolve_ref(oldref, orig_sha1, 1, &flag);
+	if (flag & REF_ISSYMREF)
+		return error("refname %s is a symbolic ref, renaming it is not supported",
+				oldref);
+	if (!symref)
 		return error("refname %s not found", oldref);
 
 	if (!is_refname_available(newref, oldref, get_packed_refs(), 0))
@@ -988,12 +1001,12 @@ int rename_ref(const char *oldref, const char *newref, const char *logmsg)
 		return error("unable to move logfile logs/%s to tmp-renamed-log: %s",
 			oldref, strerror(errno));
 
-	if (delete_ref(oldref, orig_sha1)) {
+	if (delete_ref(oldref, orig_sha1, 0)) {
 		error("unable to delete old %s", oldref);
 		goto rollback;
 	}
 
-	if (resolve_ref(newref, sha1, 1, &flag) && delete_ref(newref, sha1)) {
+	if (resolve_ref(newref, sha1, 1, &flag) && delete_ref(newref, sha1, 0)) {
 		if (errno==EISDIR) {
 			if (remove_empty_directories(git_path("%s", newref))) {
 				error("Directory not empty: %s", newref);
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index 2147eac..20b6c18 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -112,6 +112,15 @@ test_expect_success 'config information was renamed, too' \
 	"test $(git config branch.s.dummy) = Hello &&
 	 test_must_fail git config branch.s/s/dummy"
 
+test_expect_success 'renaming a symref should fail' \
+'
+	git symbolic-ref refs/heads/master2 refs/heads/master &&
+	test_must_fail git branch -m master2 master3 &&
+	git symbolic-ref refs/heads/master2 &&
+	test -f .git/refs/heads/master &&
+	! test -f .git/refs/heads/master3
+'
+
 test_expect_success \
     'git branch -m u v should fail when the reflog for u is a symlink' '
      git branch -l u &&
-- 
1.6.0.2

^ permalink raw reply related

* [PATCH 3/3] Fix git update-ref --no-deref -d.
From: Miklos Vajna @ 2008-10-27 19:50 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Jeff King, Brandon Casey, git
In-Reply-To: <cover.1225136865.git.vmiklos@frugalware.org>

Till now --no-deref was just ignored when deleting refs, fix this.

Signed-off-by: Miklos Vajna <vmiklos@frugalware.org>
---
 builtin-update-ref.c  |    8 +++++---
 t/t1400-update-ref.sh |    7 +++++++
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/builtin-update-ref.c b/builtin-update-ref.c
index d8f3142..378dc1b 100644
--- a/builtin-update-ref.c
+++ b/builtin-update-ref.c
@@ -13,7 +13,7 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix)
 {
 	const char *refname, *oldval, *msg=NULL;
 	unsigned char sha1[20], oldsha1[20];
-	int delete = 0, no_deref = 0;
+	int delete = 0, no_deref = 0, flags = 0;
 	struct option options[] = {
 		OPT_STRING( 'm', NULL, &msg, "reason", "reason of the update"),
 		OPT_BOOLEAN('d', NULL, &delete, "deletes the reference"),
@@ -47,9 +47,11 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix)
 	if (oldval && *oldval && get_sha1(oldval, oldsha1))
 		die("%s: not a valid old SHA1", oldval);
 
+	if (no_deref)
+		flags = REF_NODEREF;
 	if (delete)
-		return delete_ref(refname, oldval ? oldsha1 : NULL, 0);
+		return delete_ref(refname, oldval ? oldsha1 : NULL, flags);
 	else
 		return update_ref(msg, refname, sha1, oldval ? oldsha1 : NULL,
-				  no_deref ? REF_NODEREF : 0, DIE_ON_ERR);
+				  flags, DIE_ON_ERR);
 }
diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh
index 04c2b16..8139cd6 100755
--- a/t/t1400-update-ref.sh
+++ b/t/t1400-update-ref.sh
@@ -75,6 +75,13 @@ test_expect_success "delete $m (by HEAD)" '
 '
 rm -f .git/$m
 
+cp -f .git/HEAD .git/HEAD.orig
+test_expect_success "delete symref without dereference" '
+	git update-ref --no-deref -d HEAD &&
+	! test -f .git/HEAD
+'
+cp -f .git/HEAD.orig .git/HEAD
+
 test_expect_success '(not) create HEAD with old sha1' "
 	test_must_fail git update-ref HEAD $A $B
 "
-- 
1.6.0.2

^ permalink raw reply related

* [PATCH 0/3] symref rename/delete fixes
From: Miklos Vajna @ 2008-10-27 19:50 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Jeff King, Brandon Casey, git
In-Reply-To: <20081027085055.GL2273@genesis.frugalware.org>

On Mon, Oct 27, 2008 at 09:50:55AM +0100, Miklos Vajna <vmiklos@frugalware.org> wrote:
> Ah, I missed that. You convienced me, I'll post updated patches later
> today. :)

Here they are. The first is updated: the delete_ref() part is unchanged,
but the rename_ref() part is dropped and it just bails out with an error
if it detects a symref. The testcase is updated according to this as
well.

The two others are just rebased on top of the new first one, no
functional changes.

Miklos Vajna (3):
  Disallow git branch -m for symrefs.
  rename_ref(): handle the case when the reflog of a ref does not exist
  Fix git update-ref --no-deref -d.

 builtin-branch.c       |    2 +-
 builtin-receive-pack.c |    2 +-
 builtin-remote.c       |    4 ++--
 builtin-reset.c        |    2 +-
 builtin-send-pack.c    |    2 +-
 builtin-tag.c          |    2 +-
 builtin-update-ref.c   |    8 +++++---
 cache.h                |    2 +-
 refs.c                 |   35 ++++++++++++++++++++++++-----------
 t/t1400-update-ref.sh  |    7 +++++++
 t/t3200-branch.sh      |    9 +++++++++
 11 files changed, 53 insertions(+), 22 deletions(-)

^ permalink raw reply

* [PATCH 2/3] rename_ref(): handle the case when the reflog of a ref does not exist
From: Miklos Vajna @ 2008-10-27 19:50 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Jeff King, Brandon Casey, git
In-Reply-To: <cover.1225136865.git.vmiklos@frugalware.org>

We tried to check if a reflog of a ref is a symlink without first
checking if it exists, which is a bug.

Signed-off-by: Miklos Vajna <vmiklos@frugalware.org>
---
 refs.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/refs.c b/refs.c
index 31a2057..116eb59 100644
--- a/refs.c
+++ b/refs.c
@@ -974,7 +974,7 @@ int rename_ref(const char *oldref, const char *newref, const char *logmsg)
 	int log = !lstat(git_path("logs/%s", oldref), &loginfo);
 	const char *symref = NULL;
 
-	if (S_ISLNK(loginfo.st_mode))
+	if (log && S_ISLNK(loginfo.st_mode))
 		return error("reflog for %s is a symlink", oldref);
 
 	symref = resolve_ref(oldref, orig_sha1, 1, &flag);
-- 
1.6.0.2

^ permalink raw reply related

* Re: Working with remotes; cloning remote references
From: Marc Branchaud @ 2008-10-27 19:54 UTC (permalink / raw)
  To: Michael J Gruber; +Cc: Peter Harris, git
In-Reply-To: <48FF3FEE.8020209@drmicha.warpmail.net>

Michael J Gruber wrote:
> 
> First you should decide whether it is worth for you.

I'm still trying to figure that out...

> Comments on the
> list tend to kick in once people see a proposed implementation. A viable
> strategy could be, mimicking git submodule behaviour in part:
> 
> - Implement "git remote export reponame" which takes an existing remote
> config from .git/config, writes it to .gitremotes and checks in (or
> better: stages for commit) the file .gitremotes [you would use this on main]
> 
> - Implement "git remote import" which reads the file .gitremotes and
> adds remote config to .git/config. [you would use this on clones]
> 
> - Change "git remote update" to take updates to .gitremotes into account
> before doing its usual routine (perhaps based on a config with default
> off, or a command line option, or better both)
> 
> Downside is that .gitremotes is tracked would show up as a file in the
> repo, but I can't come up with a better way which is as simple as the
> above. .gitremotes could be stored in a specially named branch, though.

That downside is a bit disappointing.  I might as well just make "git 
remote export" simply generate a script of "git remote add" commands 
based on the contents of .git/config, and check that script in.  Then I 
could run the script in a clone to recreate the origin's remotes.

It also seems awkward to have an export step in the origin repository. 
I don't really see a need for an export step (except as an artifact of 
the above implementation).

It seems to me that this would be more natural if our hypothetical "git 
remote import <X>" could just grab the remotes from repository <X> (or 
the origin, if <X> is unspecified).  I assume that would involve 
lower-level changes than what you described, but to me it seems like the 
more usable approach.  (But then I know nothing of Git's internals, so 
maybe this kind of change would be too much work?)

		Marc

^ permalink raw reply

* [PATCH 0/2] Random patches from my tree
From: Linus Torvalds @ 2008-10-27 20:05 UTC (permalink / raw)
  To: Git Mailing List, Junio C Hamano


Ok, here's two random patches that I have in my git tree that may or may 
not be interesting.

The first one is something I did a long time ago because I was irritated 
by the "skipping inexact rename detection" message not really telling me 
_why_ it did so - just "too many files". So it just adds the information 
about number of deleted and created files.

The second one was something I whipped up due to the discussion about 
"which branch is a commit from". It adds a "--source" flag to the log 
command family, which then makes the revision walker save off the name of 
the commit in the '->util' field, and makes 'show_decorations()' show it.

So the second one allows things like

	git log --pretty=oneline --source --all

and it gives a somewhat useful view of which branch some commit came in 
on, by just showing _which_ of the references was the one that reached 
a particular commit first.

Of course, with commits that are reached multiple ways the whole notion of 
"which one reached us" is ambiguous, and it just picks one rather than 
building up any list of them. The first name we reach somethign through 
is the one that a commit sticks with. That's generally what you want.

I guess we should have a "--pretty=format" thing for it too, and maybe you 
want to support it for 'git rev-list' as well, but that's for others to 
decide - it people think it's useful.

			Linus

^ permalink raw reply

* [PATCH 1/2] Add file delete/create info when we overflow rename_limit
From: Linus Torvalds @ 2008-10-27 20:06 UTC (permalink / raw)
  To: Git Mailing List, Junio C Hamano
In-Reply-To: <alpine.LFD.2.00.0810271256470.3386@nehalem.linux-foundation.org>


When we refuse to do rename detection due to having too many files
created or deleted, let the user know the numbers.  That way there is a
reasonable starting point for setting the diff.renamelimit option.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---
 diffcore-rename.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/diffcore-rename.c b/diffcore-rename.c
index 1b2ebb4..168a95b 100644
--- a/diffcore-rename.c
+++ b/diffcore-rename.c
@@ -493,7 +493,7 @@ void diffcore_rename(struct diff_options *options)
 	if ((num_create > rename_limit && num_src > rename_limit) ||
 	    (num_create * num_src > rename_limit * rename_limit)) {
 		if (options->warn_on_too_large_rename)
-			warning("too many files, skipping inexact rename detection");
+			warning("too many files (created: %d deleted: %d), skipping inexact rename detection", num_create, num_src);
 		goto cleanup;
 	}
 
-- 
1.6.0.3.517.g759a.dirty

^ permalink raw reply related

* [PATCH 2/2] Add a 'source' decorator for commits
From: Linus Torvalds @ 2008-10-27 20:07 UTC (permalink / raw)
  To: Git Mailing List, Junio C Hamano
In-Reply-To: <alpine.LFD.2.00.0810271305500.3386@nehalem.linux-foundation.org>


We already support decorating commits by tags or branches that point to
them, but especially when we are looking at multiple branches together,
we sometimes want to see _how_ we reached a particular commit.

We can abuse the '->util' field in the commit to keep track of that as
we walk the commit lists, and get a reasonably useful view into which
branch or tag first reaches that commit.

Of course, if the commit is reachable through multiple sources (which is
common), our particular choice of "first" reachable is entirely random
and depends on the particular path we happened to follow.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---
 builtin-log.c      |    2 ++
 builtin-rev-list.c |    2 +-
 log-tree.c         |    8 +++++---
 log-tree.h         |    2 +-
 revision.c         |    4 ++++
 revision.h         |    1 +
 6 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/builtin-log.c b/builtin-log.c
index a0944f7..176cbce 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -56,6 +56,8 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix,
 		if (!strcmp(arg, "--decorate")) {
 			load_ref_decorations();
 			decorate = 1;
+		} else if (!strcmp(arg, "--source")) {
+			rev->show_source = 1;
 		} else
 			die("unrecognized argument: %s", arg);
 	}
diff --git a/builtin-rev-list.c b/builtin-rev-list.c
index 06cdeb7..857742a 100644
--- a/builtin-rev-list.c
+++ b/builtin-rev-list.c
@@ -100,7 +100,7 @@ static void show_commit(struct commit *commit)
 			children = children->next;
 		}
 	}
-	show_decorations(commit);
+	show_decorations(&revs, commit);
 	if (revs.commit_format == CMIT_FMT_ONELINE)
 		putchar(' ');
 	else
diff --git a/log-tree.c b/log-tree.c
index cec3c06..cf7947b 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -52,11 +52,13 @@ static void show_parents(struct commit *commit, int abbrev)
 	}
 }
 
-void show_decorations(struct commit *commit)
+void show_decorations(struct rev_info *opt, struct commit *commit)
 {
 	const char *prefix;
 	struct name_decoration *decoration;
 
+	if (opt->show_source && commit->util)
+		printf(" %s", (char *) commit->util);
 	decoration = lookup_decoration(&name_decoration, &commit->object);
 	if (!decoration)
 		return;
@@ -279,7 +281,7 @@ void show_log(struct rev_info *opt)
 		fputs(diff_unique_abbrev(commit->object.sha1, abbrev_commit), stdout);
 		if (opt->print_parents)
 			show_parents(commit, abbrev_commit);
-		show_decorations(commit);
+		show_decorations(opt, commit);
 		if (opt->graph && !graph_is_commit_finished(opt->graph)) {
 			putchar('\n');
 			graph_show_remainder(opt->graph);
@@ -352,7 +354,7 @@ void show_log(struct rev_info *opt)
 			printf(" (from %s)",
 			       diff_unique_abbrev(parent->object.sha1,
 						  abbrev_commit));
-		show_decorations(commit);
+		show_decorations(opt, commit);
 		printf("%s", diff_get_color_opt(&opt->diffopt, DIFF_RESET));
 		if (opt->commit_format == CMIT_FMT_ONELINE) {
 			putchar(' ');
diff --git a/log-tree.h b/log-tree.h
index 3c8127b..f2a9008 100644
--- a/log-tree.h
+++ b/log-tree.h
@@ -12,7 +12,7 @@ int log_tree_diff_flush(struct rev_info *);
 int log_tree_commit(struct rev_info *, struct commit *);
 int log_tree_opt_parse(struct rev_info *, const char **, int);
 void show_log(struct rev_info *opt);
-void show_decorations(struct commit *commit);
+void show_decorations(struct rev_info *opt, struct commit *commit);
 void log_write_email_headers(struct rev_info *opt, const char *name,
 			     const char **subject_p,
 			     const char **extra_headers_p,
diff --git a/revision.c b/revision.c
index 2f646de..d45f05a 100644
--- a/revision.c
+++ b/revision.c
@@ -199,6 +199,8 @@ static struct commit *handle_commit(struct rev_info *revs, struct object *object
 			mark_parents_uninteresting(commit);
 			revs->limited = 1;
 		}
+		if (revs->show_source && !commit->util)
+			commit->util = (void *) name;
 		return commit;
 	}
 
@@ -484,6 +486,8 @@ static int add_parents_to_list(struct rev_info *revs, struct commit *commit,
 
 		if (parse_commit(p) < 0)
 			return -1;
+		if (revs->show_source && !p->util)
+			p->util = commit->util;
 		p->object.flags |= left_flag;
 		if (!(p->object.flags & SEEN)) {
 			p->object.flags |= SEEN;
diff --git a/revision.h b/revision.h
index 2fdb2dd..51a4863 100644
--- a/revision.h
+++ b/revision.h
@@ -53,6 +53,7 @@ struct rev_info {
 			left_right:1,
 			rewrite_parents:1,
 			print_parents:1,
+			show_source:1,
 			reverse:1,
 			reverse_output_stage:1,
 			cherry_pick:1,
-- 
1.6.0.3.517.g759a.dirty

^ permalink raw reply related

* Re: [VOTE] git versus mercurial (for DragonflyBSD)
From: Brandon Casey @ 2008-10-27 20:07 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: Arne Babenhauserheide, mercurial, SLONIK.AZ, git
In-Reply-To: <200810270252.23392.jnareb@gmail.com>

Jakub Narebski wrote:
> On Mon, 27 Oct 2008, Arne Babenhauserheide wrote:
>> Also, looking at git, git users still have to garbage collect regularly, which 
>> shows to me that the design wasn't really cleaner. 
> 
> Well, they have to a lot less than they used to, and there is 
> "git gc --auto" that can be put in crontab safely.

I think you missed the most convincing argument _for_ explicit garbage collection.

By allowing explicit repository packing, git allows you to delay a cpu intensive
operation til later, when time doesn't matter, like at the end of the day right
before I go home. It also allows more cpu intensive delta/compression algorithms
to be used.

By contrast, mercurial performs deltafication and compression on each commit.
So, acceptable commit speed must be weighed against the complexity of the
deltafication/compression algorithm and file format.

-brandon

^ permalink raw reply

* Re: [VOTE] git versus mercurial (for DragonflyBSD)
From: Jakub Narebski @ 2008-10-27 20:37 UTC (permalink / raw)
  To: Brandon Casey; +Cc: Arne Babenhauserheide, mercurial, SLONIK.AZ, git
In-Reply-To: <b6jwksWkldU6N726dbI3k3yYE6WL1aXJERb9Oh1lNd8g5zdTavgRew@cipher.nrlssc.navy.mil>

On Mon, 27 Oct 2008, Brandon Casey wrote:
> Jakub Narebski wrote:
> > On Mon, 27 Oct 2008, Arne Babenhauserheide wrote:
> > >
> > > Also, looking at git, git users still have to garbage collect regularly, which 
> > > shows to me that the design wasn't really cleaner. 
> > 
> > Well, they have to a lot less than they used to, and there is 
> > "git gc --auto" that can be put in crontab safely.
> 
> I think you missed the most convincing argument _for_ explicit garbage collection.
> 
> By allowing explicit repository packing, git allows you to delay a cpu intensive
> operation til later, when time doesn't matter, like at the end of the day right
> before I go home. It also allows more cpu intensive delta/compression algorithms
> to be used.
> 
> By contrast, mercurial performs deltafication and compression on each commit.
> So, acceptable commit speed must be weighed against the complexity of the
> deltafication/compression algorithm and file format.

On the one hand one can use different compression for loose (immediate)
and packed (in a free time) objects.

On the other access from "smart" client (git://, ssh://, future "smart"
HTTP server) results in creating a pack, so we cannot allow for too
tight pack compression, or to be more exact too much CPU load taken.

The ability to vary 'quality' of pack compression is very useful to
distinguish between very loosely packed fast-import pack, and tightly
repacked in free time.

-- 
Jakub Narebski
Poland

^ permalink raw reply

* Re: [PATCH 0/2] Random patches from my tree
From: Linus Torvalds @ 2008-10-27 20:37 UTC (permalink / raw)
  To: Git Mailing List, Junio C Hamano
In-Reply-To: <alpine.LFD.2.00.0810271256470.3386@nehalem.linux-foundation.org>


On Mon, 27 Oct 2008, Linus Torvalds wrote:
> 
> So the second one allows things like
> 
> 	git log --pretty=oneline --source --all

A better example may have --abbrev-commit, at which point my current git 
tree looks like this for me:

	52be8b3... refs/heads/master Add a 'source' decorator for commits
	affba33... refs/heads/master Add file delete/create info when we overflow rename
	6806f78... refs/remotes/origin/pu Merge branch 'ar/mksnpath' into pu
	058412d... refs/remotes/origin/pu Fix potentially dangerous uses of mkpath and g
	356af64... refs/remotes/origin/pu Merge branch 'ar/maint-mksnpath' into HEAD
	9fa03c1... refs/remotes/origin/pu Fix potentially dangerous uses of mkpath and g
	94cc355... refs/remotes/origin/pu Fix mkpath abuse in dwim_ref and dwim_log of s
	108bebe... refs/remotes/origin/pu Add mksnpath which allows you to specify the o
	6af1fc2... refs/remotes/origin/man Autogenerated manpages for v1.6.0.3-523-g304d
	61b1229... refs/remotes/origin/html Autogenerated HTML docs for v1.6.0.3-523-g30
	f3ce133... refs/remotes/origin/pu Merge branch 'jc/send-pack-tell-me-more' into 
	2b37e3a... refs/remotes/origin/pu Merge branch 'jk/renamelimit' into pu
	..

ie you can see the the branch that the commits are on.

An example of the ambiguous nature would be 

	304d058... refs/remotes/origin/HEAD Merge branch 'maint'

ie because the HEAD and 'master' branches of refs/remotes/origin are the 
same, it's ambiguous which one to take, and git will have picked one at 
random. And obviously when you hit a point where two branches meet again, 
it really will depend on which branch we happened to be parsing at the 
time (which generally is "which branch had a commit date that was further 
back in history").

Another known deficiency: "gitk --source" doesn't work (neither does "gitk 
--decorate" for that matter). gitk gets very upset indeed if you try, and 
sucks up CPU cycles in some infinite loop.


		Linus

^ permalink raw reply

* Re: [VOTE] git versus mercurial (for DragonflyBSD)
From: Arne Babenhauserheide @ 2008-10-27 20:48 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git, mercurial, SLONIK.AZ
In-Reply-To: <200810271901.48925.jnareb@gmail.com>

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

Am Montag 27 Oktober 2008 19:01:48 schrieb Jakub Narebski:
> AFAIK Git mostly follows BitKeeper UI; it is quite natural as it was
> meant as replacement for BitKeeper for Linux kernel development.

It is a great choice for an SCM intended for kernel development where everyone 
knows bitkeeper, but might not be optimal for other tasks. 

> Besides is writing plugin in Python for Mercurial that much easier
> than writing new command or stuff in C for Git? Well, perhaps it is,
> as only recently there began to appear API documentation, and there
> were created utility mini-libraries like strbuf, or string_list,
> or parseopt.

Yes, for two main reasons: 

1) Writing Python is much easier and quicker than writing C, especially when 
you can just experiment with the Python interpreter (or better still: with 
ipython). No memory management hassle, no strange compiler bugs, no stray 
pointers. Just plain writing what you want to do. But if you need C speed, you 
can still include parts written in C - where you really need it. For all other 
cases you have more readable and far more compact code. 

2) You can easily access every core function, and you can replace every 
command. 
You don't have to invent a "git foolog" command. Instead you can just adapt 
the regular log to do a foolog which people can use via "hg log". 

> Also often third-party projects or stuff in contrib gets incorporated
> into git proper; sometimes stuff is moved from git core to contrib,
> if there is no maintainer however (git-svnimport, git-p4import).
> Git repository has many roots: one from git core, one with gitk
> (graphical history viewer), one from what was git mail tools, one
> with gitweb (web interface), and one with git-gui (graphical commit
> tool).

Maybe I should include the extensions in the codeswarm to have matching 
repositories. 

> The extending via plugins idea used by Mercurial, so succesfull IMHO
> for Firefox, and I think quite successfull for ikiwiki for example, is
> not without drawbacks, especially that there is no plugins clearinghouse,
> and plugins are required for what is considered pretty required
> functionality, like bisect before hg 1.0.

But they can just be included in the core distibution once they become central 
enough. 

It's a way of allowing people to add functionality they miss without forcing 
them to mess with core code instantly. 

> See also blog post on vcscompare: "Plugins In Version Control"
> http://vcscompare.blogspot.com/2008/06/plugins-in-version-cotnrol.html

I just read it, and it didn't convince me, because in my opinion a VCS has 
certain core functions which it should provide to everyone, and other 
functionality which only certain people need. 

For example I normally don't need rebasing, mercurial queues, transplanting 
and similar. Why should my tool include the commands by default? 

The defaults should be the most common way to use the tool, so people can 
easily learn it. 

Advanced stuff can be added with extensions. 

And because the most used plugins are distributed with Mercurial, I can also 
activate them when I don't control the Mercurial installation - and should 
something be missing which I need, I can just download and activate a plugin 
without having to compile anything, since they are simply Python modules. 

Just set 
[extensions]
foo = /blah/foo.py

in ~/.hgrc and the foo plugin is active. 

Gits missing plugin system might just be a reason, why its usability still 
suffers from many problems: They have to do everything for everyone all the 
time, so the chances are high, that they won't do it really good for anyone 
(but the main git coders). 

Best wishes, 
Arne

-- My stuff: http://draketo.de - stories, songs, poems, programs and stuff :)
-- Infinite Hands: http://infinite-hands.draketo.de - singing a part of the 
history of free software.
-- Ein Würfel System: http://1w6.org - einfach saubere (Rollenspiel-) Regeln.

-- PGP/GnuPG: http://draketo.de/inhalt/ich/pubkey.txt

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply

* Re: [VOTE] git versus mercurial (for DragonflyBSD)
From: Miklos Vajna @ 2008-10-27 21:07 UTC (permalink / raw)
  To: Arne Babenhauserheide; +Cc: Jakub Narebski, git, mercurial, SLONIK.AZ
In-Reply-To: <200810272149.13542.arne_bab@web.de>

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

On Mon, Oct 27, 2008 at 09:48:50PM +0100, Arne Babenhauserheide <arne_bab@web.de> wrote:
> 1) Writing Python is much easier and quicker than writing C, especially when 
> you can just experiment with the Python interpreter (or better still: with 
> ipython). No memory management hassle, no strange compiler bugs, no stray 
> pointers. Just plain writing what you want to do. But if you need C speed, you 
> can still include parts written in C - where you really need it. For all other 
> cases you have more readable and far more compact code. 

You compare Python to C here, but did you realize that in git you can
write your git command in any language you want? Of course it's
recommended to do it in C/shell/perl if you want to get it included in
git.git, but that's just a decision.

> 2) You can easily access every core function, and you can replace every 
> command. 
> You don't have to invent a "git foolog" command. Instead you can just adapt 
> the regular log to do a foolog which people can use via "hg log". 

IIRC the main reason git aliases can't overwrite git commands is because
that would break scripts relying on the output of existing git commands.
Given that I install such an extension, won't my script break?

> The defaults should be the most common way to use the tool, so people can 
> easily learn it. 
> 
> Advanced stuff can be added with extensions. 

From a user's point of view, I think external git commands and such hg
plugins are equal. The user instally the "foo"
extension/command/plugin/whatever and gets the "git/hg foo" command.

> And because the most used plugins are distributed with Mercurial, I can also 
> activate them when I don't control the Mercurial installation - and should 
> something be missing which I need, I can just download and activate a plugin 
> without having to compile anything, since they are simply Python modules. 
> 
> Just set 
> [extensions]
> foo = /blah/foo.py
> 
> in ~/.hgrc and the foo plugin is active. 

Same for git, as long as it's written in a scripting language; you
should include git-foo in PATH then you can use git foo.

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

^ permalink raw reply

* Re: [VOTE] git versus mercurial (for DragonflyBSD)
From: Arne Babenhauserheide @ 2008-10-27 21:30 UTC (permalink / raw)
  To: Miklos Vajna; +Cc: Jakub Narebski, git, mercurial, SLONIK.AZ
In-Reply-To: <20081027210716.GS2273@genesis.frugalware.org>

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

Am Montag 27 Oktober 2008 22:07:16 schrieb Miklos Vajna:
> You compare Python to C here, but did you realize that in git you can
> write your git command in any language you want? Of course it's
> recommended to do it in C/shell/perl if you want to get it included in
> git.git, but that's just a decision.

I was asked explicitely about the difference of writing a Mercurial extension 
and of writing some addition for git in C, so I answered that. 

> IIRC the main reason git aliases can't overwrite git commands is because
> that would break scripts relying on the output of existing git commands.
> Given that I install such an extension, won't my script break?

Since that "script" will likely be an extension which will use the core 
function instead of the UI command, it won't break. 

Stuff which does command line parsing can naturally break when I change the 
output. But it can also directly use the advanced features. 

> From a user's point of view, I think external git commands and such hg
> plugins are equal. The user instally the "foo"
> extension/command/plugin/whatever and gets the "git/hg foo" command.
[snip]
> Same for git, as long as it's written in a scripting language; you
> should include git-foo in PATH then you can use git foo.

Means git can provide additional commands and only has the limitation that I 
can't overwrite the basic commands, right? 

But we're slowly moving off topic, aside from "OK, git also has extensions - 
they are called external commands". 

Best wishes, 
Arne


-- My stuff: http://draketo.de - stories, songs, poems, programs and stuff :)
-- Infinite Hands: http://infinite-hands.draketo.de - singing a part of the 
history of free software.
-- Ein Würfel System: http://1w6.org - einfach saubere (Rollenspiel-) Regeln.

-- PGP/GnuPG: http://draketo.de/inhalt/ich/pubkey.txt

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply

* Re: [VOTE] git versus mercurial (for DragonflyBSD)
From: Jakub Narebski @ 2008-10-27 23:25 UTC (permalink / raw)
  To: Arne Babenhauserheide; +Cc: git, mercurial, SLONIK.AZ
In-Reply-To: <200810272149.13542.arne_bab@web.de>

Dnia poniedziałek 27. października 2008 21:48, Arne Babenhauserheide napisała:
> Am Montag 27 Oktober 2008 19:01:48 schrieb Jakub Narebski:
 
> > Besides is writing plugin in Python for Mercurial that much easier
> > than writing new command or stuff in C for Git? Well, perhaps it is,
> > as only recently there began to appear API documentation, and there
> > were created utility mini-libraries like strbuf, or string_list,
> > or parseopt.
> 
> Yes, for two main reasons: 
> 
> 1) Writing Python is much easier and quicker than writing C, especially when 
> you can just experiment with the Python interpreter (or better still: with 
> ipython). No memory management hassle, no strange compiler bugs, no stray 
> pointers. Just plain writing what you want to do. But if you need C speed, you 
> can still include parts written in C - where you really need it. For all other 
> cases you have more readable and far more compact code. 

In Git you can write in C, using (underdocumented) git API, or you can
script (in shell script, in Perl, in Python, in Ruby) using git plumbing
commands which are meant for scripting (or bindings in appropriate
language).
 
Most new features, like git-remote tool to manage interaction with
multiple remote repositories, each of which can have multiple branches,
start as a shell or Perl script, and when they and their UI mature they
get converted into C (made into builtin). Builtinification is done not
only for performance, but also for portability (think Perl support on
MS Windows).

So in Mercurial you can write in Python, or you can write in C; in Git
you can write in any scripting language (e.g. shell script, Perl, Tcl/Tk),
or you can write in C... yes, I know it is oversimplification...

> 2) You can easily access every core function, and you can replace every 
> command. 
> You don't have to invent a "git foolog" command. Instead you can just adapt 
> the regular log to do a foolog which people can use via "hg log".

Well, if I remember correctly if you drop git-foo in EXEC_PATH, then
you would be able to call it as "git foo". So adding commands is easy.

Git provides a few entry points which can be used to extend
functionality. They are: hooks system; gitattributes to define custom
merge, diff and clean/smudge (checkout) drivers per file (pathname);
custom merge strategies; EXTRENAL_DIFF and EXTERNAL_GREP.

I'm not sure if other messing with core functions is a good idea to
have such ability accessible.

> > The extending via plugins idea used by Mercurial, so succesfull IMHO
> > for Firefox, and I think quite successfull for ikiwiki for example, is
> > not without drawbacks, especially that there is no plugins clearinghouse,
> > and plugins are required for what is considered pretty required
> > functionality, like bisect before hg 1.0.
> 
> But they can just be included in the core distibution once they become central 
> enough. 

Having some extensions blessed to be included with core program (like
ikiwiki with goodstuff, and similar to Git with contrib/ section)
solves some problems of relying on extensions for basic functionality.
I for example consider bisect and patch+mail workflow tools to be basic,
while patch queue management (well, patch management in general) to be
something that can be built on top of SCM, like StGit, Guilt, TopGit
for Git, or mq (Mercurial Queues) for Mercurial.
 
>
> It's a way of allowing people to add functionality they miss without forcing 
> them to mess with core code instantly. 

The problem with extensions IMVVVHO is that they don't require to
follow strict "inclusion in core" standards, which means that there
is no pressure to add them to core... which for example leads to
including bisect in core only since hg v1.0, "because it is available
as extension".

Requiring to use large amount of extensions to having required
functionality is also one of bad consequences of extension based
development, although having default set of extensions that can be
turned on via some metaextension / metapackage (like ikiwiki's
goodstuff) reduces impact of this.
 
Extensions / modules / plugins are good in projects with high
barriers of development, like Mozilla / Firefox, GNU Emacs, etc.
but I am not sure if it doesn't make for slower core development...

> Gits missing plugin system might just be a reason, why its usability still 
> suffers from many problems: They have to do everything for everyone all the 
> time, so the chances are high, that they won't do it really good for anyone 
> (but the main git coders). 

Well, Git doesn't have plugin system, but is easily scriptable...

And, at least according to annual Git User's Survey results (on git wiki)
many people create their custom scripts and scriplets to make their work
with SCM easy...

-- 
Jakub Narebski
Poland

^ permalink raw reply

* Re: [VOTE] git versus mercurial (for DragonflyBSD)
From: Miklos Vajna @ 2008-10-28  0:13 UTC (permalink / raw)
  To: Arne Babenhauserheide; +Cc: Jakub Narebski, git, mercurial, SLONIK.AZ
In-Reply-To: <200810272230.51683.arne_bab@web.de>

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

On Mon, Oct 27, 2008 at 10:30:44PM +0100, Arne Babenhauserheide <arne_bab@web.de> wrote:
> Means git can provide additional commands and only has the limitation that I 
> can't overwrite the basic commands, right? 

Yes. And in general the API is the output of the plumbing commands, not
the API of libgit which is totally unstable.

> But we're slowly moving off topic, aside from "OK, git also has extensions - 
> they are called external commands". 

I think we're offtopic since the dragonfly list is not in cc. :)

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

^ permalink raw reply

* Re: [VOTE] git versus mercurial (for DragonflyBSD)
From: Nicolas Pitre @ 2008-10-28  1:28 UTC (permalink / raw)
  To: Jakub Narebski
  Cc: Brandon Casey, Arne Babenhauserheide, mercurial, SLONIK.AZ, git
In-Reply-To: <200810272137.07309.jnareb@gmail.com>

On Mon, 27 Oct 2008, Jakub Narebski wrote:

> On the other access from "smart" client (git://, ssh://, future "smart"
> HTTP server) results in creating a pack, so we cannot allow for too
> tight pack compression, or to be more exact too much CPU load taken.

Don't forget that, in those cases, the created pack for streaming is 
copying chunks of data from existing packs for most objects, effectively 
reusing for free the work that has previously been done to tightly 
compress those packs.


Nicolas

^ permalink raw reply


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