Git development
 help / color / mirror / Atom feed
* Re: SVN -> Git *but* with special changes
From: Andreas Schwab @ 2012-01-08 10:47 UTC (permalink / raw)
  To: Carlos Martín Nieto; +Cc: Abscissa, git
In-Reply-To: <20120108103303.GC2714@centaur.lab.cmartin.tk>

Carlos Martín Nieto <cmn@elego.de> writes:

> On Sat, Jan 07, 2012 at 09:25:27PM -0800, Abscissa wrote:
>> Well that's strange, it finished "upgrading", but now git is still just
>> reporting 1.7.0.4, which is *exactly* the same version it said before. The
>> git-svn package should already be up-to-date because I just installed it 
>> today. So I don't know what's up with that.
>
> Nothing odd about that. apt-get upgrade means "upgrade my system". If
> you want to get a newer version of package X, you do apt-get install X
> and it will install the latest version of that package.

If apt-get upgrade doesn't get you a newer version then apt-get install
won't help you either.  Both use the same installation source.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply

* Re: SVN -> Git *but* with special changes
From: Carlos Martín Nieto @ 2012-01-08 10:33 UTC (permalink / raw)
  To: Abscissa; +Cc: git
In-Reply-To: <1326000327637-7163752.post@n2.nabble.com>

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

On Sat, Jan 07, 2012 at 09:25:27PM -0800, Abscissa wrote:
> Well that's strange, it finished "upgrading", but now git is still just
> reporting 1.7.0.4, which is *exactly* the same version it said before. The
> git-svn package should already be up-to-date because I just installed it 
> today. So I don't know what's up with that.

Nothing odd about that. apt-get upgrade means "upgrade my system". If
you want to get a newer version of package X, you do apt-get install X
and it will install the latest version of that package.

Your OS seems ancient, you might be better off installing from source.

   cmn

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

^ permalink raw reply

* Re: [PATCH 2/5] run-command: kill children on exit by default
From: Junio C Hamano @ 2012-01-08  6:26 UTC (permalink / raw)
  To: Jeff King
  Cc: Clemens Buchacher, git, Jonathan Nieder, Erik Faye-Lund,
	Ilari Liusvaara, Nguyễn Thái Ngọc Duy
In-Reply-To: <20120107145004.GB2461@sigill.intra.peff.net>

Jeff King <peff@peff.net> writes:

> On Sat, Jan 07, 2012 at 12:42:44PM +0100, Clemens Buchacher wrote:
>
>> It feels natural for a user to view git commands as monolithic
>> commands with a single thread of execution. If the parent git
>> command dies, it should therefore clean up its child processes as
>> well. So enable the cleanup mechanism by default.
>
> I'm not sure this is a good idea. run_command is used in ~70 places in
> git, and I'm sure at least one of them is going to be unhappy (I see you
> found one in credential-cache, but how many others are there). I'd
> rather be conservative and leave the default the same, and then switch
> over callsites that make sense.

Yeah, I agree 100% with that reasoning. I seem to recall that was how this
commit was done in what I privately reviewed after Clemens announced his
github branch?

^ permalink raw reply

* Re: [PATCH][RFC] git on Mac OS and precomposed unicode
From: Miles Bader @ 2012-01-08  6:01 UTC (permalink / raw)
  To: Torsten Bögershausen; +Cc: git
In-Reply-To: <201201072059.23074.tboegi@web.de>

BTW, about the names, e.g. "darwin.c" etc -- is this code actually
Darwin-specific, or simply Systems-that-happen-to-force-decomposed-
unicode specific?

If the latter, maybe more generic names might be better.

Thanks,

-Miles

-- 
`To alcohol!  The cause of, and solution to,
 all of life's problems' --Homer J. Simpson

^ permalink raw reply

* Re: SVN -> Git *but* with special changes
From: Abscissa @ 2012-01-08  5:25 UTC (permalink / raw)
  To: git
In-Reply-To: <1325999865995-7163737.post@n2.nabble.com>

Well that's strange, it finished "upgrading", but now git is still just
reporting 1.7.0.4, which is *exactly* the same version it said before. The
git-svn package should already be up-to-date because I just installed it 
today. So I don't know what's up with that.


--
View this message in context: http://git.661346.n2.nabble.com/SVN-Git-but-with-special-changes-tp6840904p7163752.html
Sent from the git mailing list archive at Nabble.com.

^ permalink raw reply

* Re: SVN -> Git *but* with special changes
From: Abscissa @ 2012-01-08  5:17 UTC (permalink / raw)
  To: git
In-Reply-To: <20120108051051.GA10129@sigill.intra.peff.net>

Ok, I see. It's reporting 1.7.0, so that would explain it. One "sudo apt-get
upgrade git" and...erm...well, it seems to be upgrading my whole damn
computer, but I'll see how it all works out. Thanks!


--
View this message in context: http://git.661346.n2.nabble.com/SVN-Git-but-with-special-changes-tp6840904p7163737.html
Sent from the git mailing list archive at Nabble.com.

^ permalink raw reply

* Re: SVN -> Git *but* with special changes
From: Jeff King @ 2012-01-08  5:10 UTC (permalink / raw)
  To: Abscissa; +Cc: git
In-Reply-To: <1325999031923-7163706.post@n2.nabble.com>

On Sat, Jan 07, 2012 at 09:03:51PM -0800, Abscissa wrote:

> However, I suspect that script may not be my problem at all: If I do this:
> 
> git svn help | grep preserve
> 
> I get absolutely nothing. There doesn't seem to be a
> "--preserve-empty-dirs".

What version of git are you using? That option was added in git 1.7.7.

-Peff

^ permalink raw reply

* Re: SVN -> Git *but* with special changes
From: Abscissa @ 2012-01-08  5:03 UTC (permalink / raw)
  To: git
In-Reply-To: <20110928190445.GC1482@sigill.intra.peff.net>

>If you import with
>git-svn, it supports "--preserve-empty-dirs", which will do this for you
>automatically. 

I came across this, and it seems to mostly work:
http://john.albin.net/git/git-svn-migrate

Except it fails to do the "--preserve-empty-dirs". It does say that it
passes any options it doesn't recognize directly to git-svn, so I gave it
that, but just got:

- Cloning repository...
Unknown option: preserve-empty-dirs

Now, I realize this isn't a forum for that particular "git-svn-migrate"
tool, and I don't expect anyone to go digging though it on my account, so
I'm willing to try to add it into the script if I can just find out the
proper way to use "--preserve-empty-dirs".

However, I suspect that script may not be my problem at all: If I do this:

git svn help | grep preserve

I get absolutely nothing. There doesn't seem to be a
"--preserve-empty-dirs".


--
View this message in context: http://git.661346.n2.nabble.com/SVN-Git-but-with-special-changes-tp6840904p7163706.html
Sent from the git mailing list archive at Nabble.com.

^ permalink raw reply

* Re: [PATCH][RFC] git on Mac OS and precomposed unicode
From: Junio C Hamano @ 2012-01-08  2:46 UTC (permalink / raw)
  To: Torsten Bögershausen; +Cc: git
In-Reply-To: <201201072059.19103.tboegi@web.de>

Torsten Bögershausen <tboegi@web.de> writes:

> Implementation:
> Two files are added to the "compat" directory, darwin.h and darwin.c.
> They implement basically 3 new functions:
> darwin_opendir(), darwin_readdir() and darwin_closedir().

I haven't looked at the patch yet but that sounds exactly the right way to
go about this. Nice.

> No decomposed file names in a git repository:
> In order to prevent that ever a file name in decomposed unicode is entering
> the index, a "brute force" attempt is taken:
> all arguments into git (technically argv[1]..argv[n]) are converted into
> precomposed unicode.

That also sounds sensible, but...

> This is done in git.c by calling argv_precompose() for all commands
> except "git commit".

... I think it generally is a bad idea to say "all except foo". There may
be a reason why "foo" happens to be special in today's code, but who says
there won't be another command "bar" that shares the same reason with
"foo" to be treated specially? Or depending on the options, perhaps some
codepath of "foo" may not want the special casing and want to go through
the argv_precompose(), no?

After all, "git commit -- pathspec" will have to get the pathspec from the
command line, and match them against the paths in the index, the latter of
which you are keeping in the canonical form, so you would want the argv[]
also be in the same form, and applying your argv_precompose() would be a
sensible way to do so, no?

I would also suspect that the cleanest way to implement it is to replace
the main() entry point (see how compat/mingw.h does this).

^ permalink raw reply

* [bug] submodule --update insufficiently verbose
From: Dave Abrahams @ 2012-01-08  2:33 UTC (permalink / raw)
  To: Git Mailing List


When a "git submodule --update" fails, e.g., due to a dirty working
directory in one of the submodules, nothing is printed out indicating
the submodule or directory in which the failure occurred.  This seems
like a usability bug to me.

Thanks,

-- 
Dave Abrahams
BoostPro Computing
http://www.boostpro.com

^ permalink raw reply

* submodule add -f errs on un-ignored path
From: Neal Kreitzinger @ 2012-01-07 22:59 UTC (permalink / raw)
  To: git

git submodule add tells me to use -f because the path is ignored in 
gitconfig (even though I un-ignored it in .git/info/exclude), but with -f it 
give usage error.  (git 1.7.1)  Is this rejection by git intentional or 
unexpected?  (This is my first foray into submodules.)

/etc/gitconfig is set to excludesfile that ignores:  "WebPortal/Images/" 
entry

local .git/info/exclude is set to un-ignore it:
cat .git/info/exclude
!WebPortal/Images/
!WebPortal/Images
!WebPortal\/Images\/
!WebPortal\/Images
!WebPortal\/Images/

$ git submodule add file:///home/me/super/Images.git WebPortal/Images
Adding existing repo at 'WebPortal/Images' to the index
The following paths are ignored by one of your .gitignore files:
WebPortal/Images
Use -f if you really want to add them.
fatal: no files added
Failed to add submodule 'WebPortal/Images'
$ git submodule add -f file:///home/me/super/Images.git WebPortal/Images
Usage: git submodule [--quiet] add [-b branch] [--reference <repository>] 
[--] <
repository> [<path>]
   or: git submodule [--quiet] status [--cached] [--recursive] [--] 
[<path>...]
   or: git submodule [--quiet] init [--] [<path>...]
   or: git submodule [--quiet] update [--init] [-N|--no-fetch] [--rebase] 
[--ref
erence <repository>] [--merge] [--recursive] [--] [<path>...]
   or: git submodule [--quiet] summary [--cached|--files] [--summary-limit 
<n>]
[commit] [--] [<path>...]
   or: git submodule [--quiet] foreach [--recursive] <command>
   or: git submodule [--quiet] sync [--] [<path>...]

v/r,
neal

^ permalink raw reply

* Re: SVN -> Git *but* with special changes
From: Abscissa @ 2012-01-07 22:30 UTC (permalink / raw)
  To: git
In-Reply-To: <16808473.33899.1317229852319.JavaMail.root@mail.hq.genarts.com>

I got busy with other things and haven't had a chance to get back to this
until now. I very much appreciate the help but I'm still unclear on this
part:

>git-svn has (IMO) a good branching UI, but can be very slow for large
repositories.
>
>[1]
http://thread.gmane.org/gmane.comp.version-control.git/158940/focus=159151 :
note this thread is almost a year out of date now, and even I know much
better ways to go about this now -- but the scripts are not written. 

I don't really understand that. So...how do I convert from svn to git while
keeping branches and tags intact? If it's automated, I don't care about
speed: I can just start it and move on to other things while it's working.


--
View this message in context: http://git.661346.n2.nabble.com/SVN-Git-but-with-special-changes-tp6840904p7162793.html
Sent from the git mailing list archive at Nabble.com.

^ permalink raw reply

* [PATCH][RFC] git on Mac OS and precomposed unicode
From: Torsten Bögershausen @ 2012-01-07 19:59 UTC (permalink / raw)
  To: git; +Cc: tboegi

Allow git on Mac OS to store file names in the index in precomposed unicode,
while the file system used decomposed unicode.

When a file called "LATIN CAPITAL LETTER A WITH DIAERESIS"
(in utf-8 encoded as 0xc3 0x84) is created,
the filesystem converts "precomposed unicode" into "decomposed unicode",
which means that readdir() will return 0x41 0xcc 0x88.
When true, git reverts the unicode decomposition of filenames.
This is useful when pulling/pushing from repositories containing utf-8
encoded filenames using precomposed utf-8 (like Linux).

This feature is automatically switched on when "git init" is run,
and the file system is doing UTF-8 decompostion.
(Which has been observed on HFS+, SMBFS and VFAT, but not on NFS)
It can be switched off by setting core.macosforcenfc=false

It is implemented by re-defining the readdir() functions.
File names are converted into precomposed UTF-8.

Signed-off-by: Torsten Bögershausen <tboegi@web.de>
---
 Documentation/config.txt     |    9 ++
 Makefile                     |    3 +
 builtin/init-db.c            |   22 +++++
 compat/darwin.c              |  200 ++++++++++++++++++++++++++++++++++++++++++
 compat/darwin.h              |   31 +++++++
 git-compat-util.h            |    8 ++
 git.c                        |    1 +
 t/t0050-filesystem.sh        |    1 +
 t/t3910-mac-os-precompose.sh |  104 ++++++++++++++++++++++
 9 files changed, 379 insertions(+), 0 deletions(-)
 create mode 100644 compat/darwin.c
 create mode 100644 compat/darwin.h
 create mode 100755 t/t3910-mac-os-precompose.sh

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 2959390..01b9465 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -175,6 +175,15 @@ The default is false, except linkgit:git-clone[1] or linkgit:git-init[1]
 will probe and set core.ignorecase true if appropriate when the repository
 is created.
 
+core.precomposedunicode::
+	This option is only used by Mac OS implementation of git.
+	When core.precomposedunicode=true,
+	git reverts the unicode decomposition of filenames done by Mac OS.
+	This is useful when pulling/pushing from repositories containing utf-8
+	encoded filenames using precomposed unicode (like Linux).
+	When false, file names are handled fully transparent by git.
+	If in doubt, set core.precomposedunicode=false.
+
 core.trustctime::
 	If false, the ctime differences between the index and the
 	working tree are ignored; useful when the inode change time
diff --git a/Makefile b/Makefile
index b21d2f1..596900e 100644
--- a/Makefile
+++ b/Makefile
@@ -519,6 +519,7 @@ LIB_H += compat/bswap.h
 LIB_H += compat/cygwin.h
 LIB_H += compat/mingw.h
 LIB_H += compat/obstack.h
+LIB_H += compat/darwin.h
 LIB_H += compat/win32/pthread.h
 LIB_H += compat/win32/syslog.h
 LIB_H += compat/win32/poll.h
@@ -884,6 +885,8 @@ ifeq ($(uname_S),Darwin)
 	endif
 	NO_MEMMEM = YesPlease
 	USE_ST_TIMESPEC = YesPlease
+	COMPAT_OBJS += compat/darwin.o
+	BASIC_CFLAGS += -DPRECOMPOSED_UNICODE
 endif
 ifeq ($(uname_S),SunOS)
 	NEEDS_SOCKET = YesPlease
diff --git a/builtin/init-db.c b/builtin/init-db.c
index 0dacb8b..88c9de1 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -290,6 +290,28 @@ static int create_default_files(const char *template_path)
 		strcpy(path + len, "CoNfIg");
 		if (!access(path, F_OK))
 			git_config_set("core.ignorecase", "true");
+#if defined (PRECOMPOSED_UNICODE)
+		{
+			const static char *auml_nfc = "\xc3\xa4";
+			const static char *auml_nfd = "\x61\xcc\x88";
+			int output_fd;
+			path[len] = 0;
+			strcpy(path + len, auml_nfc);
+			output_fd = open(path, O_CREAT|O_EXCL|O_RDWR, 0600);
+			if (output_fd >=0) {
+				close(output_fd);
+				path[len] = 0;
+				strcpy(path + len, auml_nfd);
+				if (0 == access(path, R_OK))
+					git_config_set("core.precomposedunicode", "true");
+				else
+					git_config_set("core.precomposedunicode", "false");
+				path[len] = 0;
+				strcpy(path + len, auml_nfc);
+				unlink(path);
+			}
+		}
+#endif
 	}
 
 	return reinit;
diff --git a/compat/darwin.c b/compat/darwin.c
new file mode 100644
index 0000000..15de7c2
--- /dev/null
+++ b/compat/darwin.c
@@ -0,0 +1,200 @@
+#define __DARWIN_C__
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdint.h>
+
+#include "../cache.h"
+#include "../utf8.h"
+
+#include "darwin.h"
+
+static int mac_os_precomposed_unicode;
+const static char *repo_encoding = "UTF-8";
+const static char *path_encoding = "UTF-8-MAC";
+
+
+/* Code borrowed from utf8.c */
+#if defined(OLD_ICONV) || (defined(__sun__) && !defined(_XPG6))
+	typedef const char * iconv_ibp;
+#else
+	typedef char * iconv_ibp;
+#endif
+static char *reencode_string_iconv(const char *in, size_t insz, iconv_t conv)
+{
+	size_t outsz, outalloc;
+	char *out, *outpos;
+	iconv_ibp cp;
+
+	outsz = insz;
+	outalloc = outsz + 1; /* for terminating NUL */
+	out = xmalloc(outalloc);
+	outpos = out;
+	cp = (iconv_ibp)in;
+
+	while (1) {
+		size_t cnt = iconv(conv, &cp, &insz, &outpos, &outsz);
+
+		if (cnt == -1) {
+			size_t sofar;
+			if (errno != E2BIG) {
+				free(out);
+				iconv_close(conv);
+				return NULL;
+			}
+			/* insz has remaining number of bytes.
+			 * since we started outsz the same as insz,
+			 * it is likely that insz is not enough for
+			 * converting the rest.
+			 */
+			sofar = outpos - out;
+			outalloc = sofar + insz * 2 + 32;
+			out = xrealloc(out, outalloc);
+			outpos = out + sofar;
+			outsz = outalloc - sofar - 1;
+		}
+		else {
+			*outpos = '\0';
+			break;
+		}
+	}
+	return out;
+}
+
+static size_t
+has_utf8(const char *s, size_t maxlen, size_t *strlen_c)
+{
+	const uint8_t *utf8p = (const uint8_t*) s;
+	size_t strlen_chars = 0;
+	size_t ret = 0;
+
+	if ((!utf8p) || (!*utf8p))
+		return 0;
+
+	while((*utf8p) && maxlen) {
+		if (*utf8p & 0x80)
+			ret++;
+		strlen_chars++;
+		utf8p++;
+		maxlen--;
+	}
+	if (strlen_c)
+		*strlen_c = strlen_chars;
+
+	return ret;
+}
+
+static int
+precomposed_unicode_config(const char *var, const char *value, void *cb)
+{
+	if (!strcasecmp(var, "core.precomposedunicode")) {
+		mac_os_precomposed_unicode = git_config_bool(var, value);
+		return 0;
+	}
+	return 1;
+}
+
+void
+argv_precompose(int argc, const char **argv)
+{
+	int i = 0;
+	const char *oldarg;
+	char *newarg;
+	iconv_t ic_precompose;
+
+	if (!strcmp("commit", argv[0]))
+		return;
+
+	git_config(precomposed_unicode_config, NULL);
+	if (!mac_os_precomposed_unicode)
+		return;
+
+	ic_precompose = iconv_open(repo_encoding, path_encoding);
+	if (ic_precompose == (iconv_t) -1)
+		return;
+
+	while (i < argc) {
+		size_t namelen;
+		oldarg = argv[i];
+
+		if (has_utf8(oldarg, (size_t)-1, &namelen)) {
+			newarg = reencode_string_iconv(oldarg, namelen, ic_precompose);
+			if (newarg)
+				argv[i] = newarg;
+		}
+		i++;
+	}
+	iconv_close(ic_precompose);
+}
+
+
+DARWIN_DIR *
+darwin_opendir(const char *dirname)
+{
+	DARWIN_DIR *darwin_dir;
+	darwin_dir = malloc(sizeof(DARWIN_DIR));
+	if (!darwin_dir)
+		return NULL;
+
+	darwin_dir->dirp = opendir(dirname);
+	if (!darwin_dir->dirp) {
+		free(darwin_dir);
+		return NULL;
+	}
+	darwin_dir->ic_precompose = iconv_open(repo_encoding, path_encoding);
+	if (darwin_dir->ic_precompose == (iconv_t) -1) {
+		closedir(darwin_dir->dirp);
+		free(darwin_dir);
+		return NULL;
+	}
+
+	return darwin_dir;
+}
+
+struct dirent *
+darwin_readdir(DARWIN_DIR *darwin_dirp)
+{
+	struct dirent *res;
+	size_t namelen = 0;
+
+	res = readdir(darwin_dirp->dirp);
+	if (!res || !mac_os_precomposed_unicode || !has_utf8(res->d_name, (size_t)-1, &namelen))
+		return res;
+	else {
+		int olderrno = errno;
+		size_t outsz = sizeof(darwin_dirp->dirent_nfc.d_name) - 1; /* one for \0 */
+		char *outpos = darwin_dirp->dirent_nfc.d_name;
+		iconv_ibp cp;
+		size_t cnt;
+		size_t insz = namelen;
+		cp = (iconv_ibp)res->d_name;
+
+		/* Copy all data except the name */
+		memcpy(&darwin_dirp->dirent_nfc,
+					 res,
+					 sizeof(darwin_dirp->dirent_nfc)-sizeof(darwin_dirp->dirent_nfc.d_name));
+		errno = 0;
+
+		cnt = iconv(darwin_dirp->ic_precompose, &cp, &insz, &outpos, &outsz);
+		if (cnt < sizeof(darwin_dirp->dirent_nfc.d_name) -1) {
+			*outpos = 0;
+			errno = olderrno;
+			return &darwin_dirp->dirent_nfc;
+		}
+		errno = olderrno;
+		return res;
+	}
+}
+
+
+int
+darwin_closedir(DARWIN_DIR *darwin_dirp)
+{
+	int ret_value;
+	ret_value = closedir(darwin_dirp->dirp);
+	if (darwin_dirp->ic_precompose != (iconv_t)-1)
+		iconv_close(darwin_dirp->ic_precompose);
+	free(darwin_dirp);
+	return ret_value;
+}
diff --git a/compat/darwin.h b/compat/darwin.h
new file mode 100644
index 0000000..094f930
--- /dev/null
+++ b/compat/darwin.h
@@ -0,0 +1,31 @@
+#ifndef __DARWIN_H__
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <iconv.h>
+
+
+typedef struct {
+	iconv_t ic_precompose;
+	DIR *dirp;
+	struct dirent dirent_nfc;
+} DARWIN_DIR;
+
+char *str_precompose(const char *in, iconv_t ic_precompose);
+
+void argv_precompose(int argc, const char **argv);
+
+DARWIN_DIR *darwin_opendir(const char *dirname);
+struct dirent *darwin_readdir(DARWIN_DIR *dirp);
+int darwin_closedir(DARWIN_DIR *dirp);
+
+#ifndef __DARWIN_C__
+#define opendir(n) darwin_opendir(n)
+#define readdir(d) darwin_readdir(d)
+#define closedir(d) darwin_closedir(d)
+#define DIR DARWIN_DIR
+
+#endif  /* __DARWIN_C__ */
+
+#define  __DARWIN_H__
+#endif /* __DARWIN_H__ */
diff --git a/git-compat-util.h b/git-compat-util.h
index 230e198..859dfcf 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -90,6 +90,14 @@
 #include <windows.h>
 #endif
 
+#if defined (PRECOMPOSED_UNICODE)
+#include "compat/darwin.h"
+#else
+#define str_precompose(in,i_nfd2nfc) (NULL)
+#define argv_precompose(c,v)
+
+#endif
+
 #include <unistd.h>
 #include <stdio.h>
 #include <sys/stat.h>
diff --git a/git.c b/git.c
index 8e34903..6b2ffb7 100644
--- a/git.c
+++ b/git.c
@@ -298,6 +298,7 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
 		    startup_info->have_repository) /* get_git_dir() may set up repo, avoid that */
 			trace_repo_setup(prefix);
 	}
+	argv_precompose(argc, argv);
 	commit_pager_choice();
 
 	if (!help && p->option & NEED_WORK_TREE)
diff --git a/t/t0050-filesystem.sh b/t/t0050-filesystem.sh
index 1542cf6..befe39e 100755
--- a/t/t0050-filesystem.sh
+++ b/t/t0050-filesystem.sh
@@ -126,6 +126,7 @@ test_expect_success "setup unicode normalization tests" '
 
   test_create_repo unicode &&
   cd unicode &&
+  git config core.precomposedunicode false &&
   touch "$aumlcdiar" &&
   git add "$aumlcdiar" &&
   git commit -m initial &&
diff --git a/t/t3910-mac-os-precompose.sh b/t/t3910-mac-os-precompose.sh
new file mode 100755
index 0000000..d4763c5
--- /dev/null
+++ b/t/t3910-mac-os-precompose.sh
@@ -0,0 +1,104 @@
+#!/bin/sh
+#
+# Copyright (c) 2012 Torsten Bögershausen
+#
+
+test_description='utf-8 decomposed (nfd) converted to precomposed (nfc)'
+
+. ./test-lib.sh
+
+Adiarnfc=`printf '\303\204'`
+Odiarnfc=`printf '\303\226'`
+Adiarnfd=`printf 'A\314\210'`
+Odiarnfd=`printf 'O\314\210'`
+
+mkdir junk &&
+>junk/"$Adiarnfc" &&
+case "$(cd junk && echo *)" in
+	"$Adiarnfd")
+	test_nfd=1
+	;;
+	*)	;;
+esac
+rm -rf junk
+
+if test "$test_nfd"
+then
+	test_expect_success "detect if nfd needed" '
+		precomposedunicode=`git config --bool core.precomposedunicode` &&
+		test "$precomposedunicode" = true
+	'
+	test_expect_success "setup" '
+		>x &&
+		git add x &&
+		git commit -m "1st commit" &&
+		git rm x &&
+		git commit -m "rm x"
+	'
+	test_expect_success "setup case mac" '
+	git checkout -b mac_os
+	'
+	# This will test nfd2nfc in readdir()
+	test_expect_success "add file Adiarnfc" '
+		echo f.Adiarnfc >f.$Adiarnfc &&
+		git add f.$Adiarnfc &&
+		git commit -m "add f.$Adiarnfc"
+	'
+	# This will test nfd2nfc in git add()
+	test_expect_success "stage file d.Adiarnfd/f.Adiarnfd" '
+		mkdir d.$Adiarnfd &&
+		echo d.$Adiarnfd/f.$Adiarnfd >d.$Adiarnfd/f.$Adiarnfd &&
+		git stage d.$Adiarnfd/f.$Adiarnfd &&
+		git commit -m "add d.$Adiarnfd/f.$Adiarnfd"
+	'
+	test_expect_success "add link Adiarnfc" '
+		ln -s d.$Adiarnfd/f.$Adiarnfd l.$Adiarnfc &&
+		git add l.$Adiarnfc &&
+		git commit -m "add l.Adiarnfc"
+	'
+	# This will test git log
+	test_expect_success "git log f.Adiar" '
+		git log f.$Adiarnfc > f.Adiarnfc.log &&
+		git log f.$Adiarnfd > f.Adiarnfd.log &&
+		test -s f.Adiarnfc.log &&
+		test -s f.Adiarnfd.log &&
+		test_cmp f.Adiarnfc.log f.Adiarnfd.log &&
+		rm f.Adiarnfc.log f.Adiarnfd.log
+	'
+	# This will test git ls-files
+	test_expect_success "git lsfiles f.Adiar" '
+		git ls-files f.$Adiarnfc > f.Adiarnfc.log &&
+		git ls-files f.$Adiarnfd > f.Adiarnfd.log &&
+		test -s f.Adiarnfc.log &&
+		test -s f.Adiarnfd.log &&
+		test_cmp f.Adiarnfc.log f.Adiarnfd.log &&
+		rm f.Adiarnfc.log f.Adiarnfd.log
+	'
+	# This will test git mv
+	test_expect_success "git mv" '
+		git mv f.$Adiarnfd f.$Odiarnfc &&
+		git mv d.$Adiarnfd d.$Odiarnfc &&
+		git mv l.$Adiarnfd l.$Odiarnfc &&
+		git commit -m "mv Adiarnfd Odiarnfc"
+	'
+	# Files can be checked out as nfc
+	# And the link has been corrected from nfd to nfc
+	test_expect_success "git checkout nfc" '
+		rm f.$Odiarnfc &&
+		git checkout f.$Odiarnfc
+	'
+	# Make it possible to checkout files with their NFD names
+	test_expect_success "git checkout file nfd" '
+		rm -f f.* &&
+		git checkout f.$Odiarnfd
+	'
+	# Make it possible to checkout links with their NFD names
+	test_expect_success "git checkout link nfd" '
+		rm l.* &&
+		git checkout l.$Odiarnfd
+	'
+else
+	 say "Skipping nfc/nfd tests"
+fi
+
+test_done
-- 
1.7.8.rc0.43.gb49a8

^ permalink raw reply related

* [PATCH][RFC] git on Mac OS and precomposed unicode
From: Torsten Bögershausen @ 2012-01-07 19:59 UTC (permalink / raw)
  To: git; +Cc: tboegi

Purpose:
This patch is a suggestion to work around the unpleasenties
when Mac OS is decomposing unicode filenames.

The suggested change:
a) is only used under Mac OS
b) can be switched off by a configuration variable
c) is optimized to handle ASCII only filename
d) will improve the interwork between Mac OS, Linux and Windows*
   via git push/pull, using USB sticks (technically speaking VFAT)
   or mounted network shares using samba.

* (Not all Windows versions support UTF-8 yet:
   Msysgit needs the unicode branch, cygwin supports UTF-8 since 1.7)


Runtime configuration:
A new confguration variable is added: "core.precomposedunicode"
This variable is only used on Mac OS.
If set to false, git behaves exactly as older versions of git.
When a new git version is installed and there is a repository
where the configuration "core.precomposedunicode" is not present,
the new git is backward compatible.

When core.precomposedunicode=true, all filenames are stored in precomposed
unicode in the index (technically speaking precomposed UTF-8).
Even when readdir() under Mac OS returns filenames as decomposed.

Implementation:
Two files are added to the "compat" directory, darwin.h and darwin.c.
They implement basically 3 new functions:
darwin_opendir(), darwin_readdir() and darwin_closedir().


Compile time configuration:
A new compiler option PRECOMPOSED_UNICODE is introduced in the Makefile,
so that the patch can be switched off completely at compile time.

No decomposed file names in a git repository:
In order to prevent that ever a file name in decomposed unicode is entering
the index, a "brute force" attempt is taken:
all arguments into git (technically argv[1]..argv[n]) are converted into
precomposed unicode.
This is done in git.c by calling argv_precompose() for all commands
except "git commit".
This function is actually a #define, and it is only defined under Mac OS.
Nothing is converted on any other OS.

Implementation details:
The main work is done in darwin_readdir() and argv_precompose().
The conversion into precomposed unicode is done by using iconv,
where decomposed is denoted by "UTF-8-MAC" and precomposed is "UTF-8".
When already precomposed unicode is precomposed, the string is returned
unchanged.

Thread save:
Since there is no need for argv_precompose()to be thread-save, one iconv
instance is created at the beginning and kept for all conversions.
Even readdir() is not thread-save, so that darwin_opendir() will call
iconv_open() once and keep the instance for all calls of darwin_readdir()
until darwin_close() is called.

Auto sensing:
When creating a new git repository with "git init" or "git clone", the
"core.precomposedunicode" will be set automatically to "true" or "false".

Typically core.precomposedunicode is "true" on HFS and VFAT.
It is even true for file systems mounted via SAMBA onto a Linux box,
and "false" for drives mounted via NFS onto a Linux box.


New test case:
The new t3910-mac-os-precompose.sh is added to check if a filename
can be reached either in precomposed or decomposed unicode (NFC or NFD).


 Documentation/config.txt     |    9 ++
 Makefile                     |    3 +
 builtin/init-db.c            |   22 +++++
 compat/darwin.c              |  200 ++++++++++++++++++++++++++++++++++++++++++
 compat/darwin.h              |   31 +++++++
 git-compat-util.h            |    8 ++
 git.c                        |    1 +
 t/t0050-filesystem.sh        |    1 +
 t/t3910-mac-os-precompose.sh |  104 ++++++++++++++++++++++
 9 files changed, 379 insertions(+), 0 deletions(-)
 create mode 100644 compat/darwin.c
 create mode 100644 compat/darwin.h
 create mode 100755 t/t3910-mac-os-precompose.sh

-- 
1.7.8.rc0.43.gb49a8

^ permalink raw reply

* [PATCH] git-gui: fix selection regression introduced in a8ca786991
From: Bert Wesarg @ 2012-01-07 19:43 UTC (permalink / raw)
  To: Pat Thoyts; +Cc: git, Bert Wesarg

While fixing the problem from a8ca786991, it introduces a regression
regarding what happen after the multi selected file operation (ie.
one of Ctrl-{T,U,J}) because the next selected file could not be handled
by such a subsequent file operation.

The right way is to move the fix from this commit down into the show_diff
function. So that all code path add the current diff path to the list of
selections.

This also simplifies helper functions for these operatione which needed
to handle the case whether there is only the current diff path or also
a selction.

Signed-off-by: Bert Wesarg <bert.wesarg@googlemail.com>
---

I propbose this to be inlcuded in the next git-1.7.9 release.

 git-gui.sh    |    1 -
 lib/diff.tcl  |    3 ++-
 lib/index.tcl |   48 +++++++++++++++---------------------------------
 3 files changed, 17 insertions(+), 35 deletions(-)

diff --git a/git-gui.sh b/git-gui.sh
index ba4e5c1..13b22dd 100755
--- a/git-gui.sh
+++ b/git-gui.sh
@@ -2520,7 +2520,6 @@ proc toggle_or_diff {w x y} {
 				[concat $after [list ui_ready]]
 		}
 	} else {
-		set selected_paths($path) 1
 		show_diff $path $w $lno
 	}
 }
diff --git a/lib/diff.tcl b/lib/diff.tcl
index ec44055..775649c 100644
--- a/lib/diff.tcl
+++ b/lib/diff.tcl
@@ -75,7 +75,7 @@ A rescan will be automatically started to find other files which may have the sa
 }
 
 proc show_diff {path w {lno {}} {scroll_pos {}} {callback {}}} {
-	global file_states file_lists
+	global file_states file_lists selected_paths
 	global is_3way_diff is_conflict_diff diff_active repo_config
 	global ui_diff ui_index ui_workdir
 	global current_diff_path current_diff_side current_diff_header
@@ -91,6 +91,7 @@ proc show_diff {path w {lno {}} {scroll_pos {}} {callback {}}} {
 		}
 	}
 	if {$lno >= 1} {
+		set selected_paths($path) 1
 		$w tag add in_diff $lno.0 [expr {$lno + 1}].0
 		$w see $lno.0
 	}
diff --git a/lib/index.tcl b/lib/index.tcl
index 8efbbdd..2223a21 100644
--- a/lib/index.tcl
+++ b/lib/index.tcl
@@ -287,17 +287,11 @@ proc unstage_helper {txt paths} {
 }
 
 proc do_unstage_selection {} {
-	global current_diff_path selected_paths
-
-	if {[array size selected_paths] > 0} {
-		unstage_helper \
-			{Unstaging selected files from commit} \
-			[array names selected_paths]
-	} elseif {$current_diff_path ne {}} {
-		unstage_helper \
-			[mc "Unstaging %s from commit" [short_path $current_diff_path]] \
-			[list $current_diff_path]
-	}
+	global selected_paths
+
+	unstage_helper \
+		{Unstaging selected files from commit} \
+		[array names selected_paths]
 }
 
 proc add_helper {txt paths} {
@@ -339,17 +333,11 @@ proc add_helper {txt paths} {
 }
 
 proc do_add_selection {} {
-	global current_diff_path selected_paths
-
-	if {[array size selected_paths] > 0} {
-		add_helper \
-			{Adding selected files} \
-			[array names selected_paths]
-	} elseif {$current_diff_path ne {}} {
-		add_helper \
-			[mc "Adding %s" [short_path $current_diff_path]] \
-			[list $current_diff_path]
-	}
+	global selected_paths
+
+	add_helper \
+		{Adding selected files} \
+		[array names selected_paths]
 }
 
 proc do_add_all {} {
@@ -452,17 +440,11 @@ proc revert_helper {txt paths} {
 }
 
 proc do_revert_selection {} {
-	global current_diff_path selected_paths
-
-	if {[array size selected_paths] > 0} {
-		revert_helper \
-			[mc "Reverting selected files"] \
-			[array names selected_paths]
-	} elseif {$current_diff_path ne {}} {
-		revert_helper \
-			[mc "Reverting %s" [short_path $current_diff_path]] \
-			[list $current_diff_path]
-	}
+	global selected_paths
+
+	revert_helper \
+		[mc "Reverting selected files"] \
+		[array names selected_paths]
 }
 
 proc do_select_commit_type {} {
-- 
1.7.8.1.873.gfea665

^ permalink raw reply related

* Re: How to deal with historic tar-balls
From: Neal Kreitzinger @ 2012-01-07 19:18 UTC (permalink / raw)
  To: nn6eumtr; +Cc: git
In-Reply-To: <4F079BA1.3060907@gmail.com>

On 1/6/2012 7:10 PM, nn6eumtr wrote:
> Thanks for the response, there is lots of good information there.
>
> One clarification - can you track renames in git? I tried using git mv 
> but from the status output it looks like it deleted the old file  and 
> added the new file. I was expecting it to record some sort of 
> indicator of the name change, instead it looks like a short-cut for 
> delete & add, the docs aren't clear if that is the case.
>
(note: top-posting is not advised.)
You are exactly right in your observation:  git-mv is only a shortcut 
for 'remove old then add new'.  Git does not explicitly track 
"renames".  It can detect renames easily in the cases where you really 
just renamed the file and left the contents the same.  Git tracks 
content (and trees) as opposed to files (and file names).  Git stores 
the 'blob', aka 'contents' of files in the object store.  So if you have 
30 files with different names and the exact same contents in your work 
tree they are stored as a single blob in the .git/objects "object 
store".  If some of your "renames" are really "I renamed it and then I 
modified it" then git will have a harder time detecting the "rename" 
depending on how much you modified it.  In such cases what you really 
did is arguably not a "rename" anyway.  You can record your "renames" 
manually in your commit message if appropriate.  If you have 5 minutes 
you can watch this video from the 15:00 min to 20:59 min marks to get an 
explanation of git-mv and rename-detection: 
http://www.youtube.com/watch?v=j45cs5_nY2k (youtube searchstring: 'git 
google tech talks', result: 'contributing with git'.)

v/r,
neal

^ permalink raw reply

* Re: [PATCH] credentials: unable to connect to cache daemon
From: Jeff King @ 2012-01-07 14:55 UTC (permalink / raw)
  To: Clemens Buchacher
  Cc: Junio C Hamano, git, Jonathan Nieder, Erik Faye-Lund,
	Ilari Liusvaara, Nguyễn Thái Ngọc Duy
In-Reply-To: <20120107115434.GA8568@ecki.lan>

On Sat, Jan 07, 2012 at 12:54:36PM +0100, Clemens Buchacher wrote:

> Error out if we just spawned the daemon and yet we cannot connect.

Actually it was intentional not to produce an error. The cache helper is
just a cache, so I consider it "best effort", and if it cannot cache a
password, it's not the end of the world. Git should continue, anyway.

That being said, it's probably nicer to be informative in this case than
not, since it is a configuration error the user probably would like to
fix. And since the rewrite of the credential helper API, it's OK for
helpers to return a failing exit code; git will just ignore it and keep
going.

So I think this is a reasonable thing to do.

Acked-by: Jeff King <peff@peff.net>

> And always release the string buffer.

Oops, thanks.

-Peff

^ permalink raw reply

* Re: [PATCH 2/5] run-command: kill children on exit by default
From: Jeff King @ 2012-01-07 14:50 UTC (permalink / raw)
  To: Clemens Buchacher
  Cc: Junio C Hamano, git, Jonathan Nieder, Erik Faye-Lund,
	Ilari Liusvaara, Nguyễn Thái Ngọc Duy
In-Reply-To: <1325936567-3136-3-git-send-email-drizzd@aon.at>

On Sat, Jan 07, 2012 at 12:42:44PM +0100, Clemens Buchacher wrote:

> It feels natural for a user to view git commands as monolithic
> commands with a single thread of execution. If the parent git
> command dies, it should therefore clean up its child processes as
> well. So enable the cleanup mechanism by default.

I'm not sure this is a good idea. run_command is used in ~70 places in
git, and I'm sure at least one of them is going to be unhappy (I see you
found one in credential-cache, but how many others are there). I'd
rather be conservative and leave the default the same, and then switch
over callsites that make sense.

-Peff

PS I thought this would certainly break the pager, since it should
   outlast us after we finish producing output. But I think at one point
   I switched the pager invocation so that the git wrapper lives and
   waits until the pager dies.

^ permalink raw reply

* [PATCH v4] clone: add --single-branch to fetch only one branch
From: Nguyễn Thái Ngọc Duy @ 2012-01-07 14:45 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Shawn O. Pearce,
	Nguyễn Thái Ngọc Duy
In-Reply-To: <1325833869-20078-1-git-send-email-pclouds@gmail.com>

When --single-branch is given, only one branch, either HEAD or one
specified by --branch, will be fetched. Also only tags that point to
the downloaded history are fetched.

This helps most in shallow clones, where it can reduce the download to
minimum and that is why it is enabled by default when --depth is given.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 The fourth round does not limit --single-branch to shallow clones any
 more. I did not see that the patch finally comes close to what Carlos
 tried to do [1], the patch that reminded me of the tag issue in shallow
 clone Shawn mentioned a while ago.

 [1] http://thread.gmane.org/gmane.comp.version-control.git/187639

 Documentation/git-clone.txt |   11 ++++++-
 builtin/clone.c             |   52 ++++++++++++++++++++++++++++--
 t/t5500-fetch-pack.sh       |   72 ++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 129 insertions(+), 6 deletions(-)

diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
index 4b8b26b..0931a3e 100644
--- a/Documentation/git-clone.txt
+++ b/Documentation/git-clone.txt
@@ -13,7 +13,8 @@ SYNOPSIS
 	  [-l] [-s] [--no-hardlinks] [-q] [-n] [--bare] [--mirror]
 	  [-o <name>] [-b <name>] [-u <upload-pack>] [--reference <repository>]
 	  [--separate-git-dir <git dir>]
-	  [--depth <depth>] [--recursive|--recurse-submodules] [--] <repository>
+	  [--depth <depth>] [--[no-]single-branch]
+	  [--recursive|--recurse-submodules] [--] <repository>
 	  [<directory>]
 
 DESCRIPTION
@@ -179,6 +180,14 @@ objects from the source repository into a pack in the cloned repository.
 	with a long history, and would want to send in fixes
 	as patches.
 
+--single-branch::
+	Clone only the history leading to the tip of a single branch,
+	either specified by the `--branch` option or the primary
+	branch remote's `HEAD` points at. When creating a shallow
+	clone with the `--depth` option, this is the default, unless
+	`--no-single-branch` is given to fetch the histories near the
+	tips of all branches.
+
 --recursive::
 --recurse-submodules::
 	After the clone is created, initialize all submodules within,
diff --git a/builtin/clone.c b/builtin/clone.c
index 86db954..9dcc5fe 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -37,7 +37,7 @@ static const char * const builtin_clone_usage[] = {
 	NULL
 };
 
-static int option_no_checkout, option_bare, option_mirror;
+static int option_no_checkout, option_bare, option_mirror, option_single_branch = -1;
 static int option_local, option_no_hardlinks, option_shared, option_recursive;
 static char *option_template, *option_depth;
 static char *option_origin = NULL;
@@ -48,6 +48,7 @@ static int option_verbosity;
 static int option_progress;
 static struct string_list option_config;
 static struct string_list option_reference;
+static const char *src_ref_prefix = "refs/heads/";
 
 static int opt_parse_reference(const struct option *opt, const char *arg, int unset)
 {
@@ -92,6 +93,8 @@ static struct option builtin_clone_options[] = {
 		   "path to git-upload-pack on the remote"),
 	OPT_STRING(0, "depth", &option_depth, "depth",
 		    "create a shallow clone of that depth"),
+	OPT_BOOL(0, "single-branch", &option_single_branch,
+		    "clone only one branch, HEAD or --branch"),
 	OPT_STRING(0, "separate-git-dir", &real_git_dir, "gitdir",
 		   "separate git dir from working tree"),
 	OPT_STRING_LIST('c', "config", &option_config, "key=value",
@@ -427,8 +430,28 @@ static struct ref *wanted_peer_refs(const struct ref *refs,
 	struct ref *local_refs = head;
 	struct ref **tail = head ? &head->next : &local_refs;
 
-	get_fetch_map(refs, refspec, &tail, 0);
-	if (!option_mirror)
+	if (option_single_branch) {
+		struct ref *remote_head = NULL;
+
+		if (!option_branch)
+			remote_head = guess_remote_head(head, refs, 0);
+		else {
+			struct strbuf sb = STRBUF_INIT;
+			strbuf_addstr(&sb, src_ref_prefix);
+			strbuf_addstr(&sb, option_branch);
+			remote_head = find_ref_by_name(refs, sb.buf);
+			strbuf_release(&sb);
+		}
+
+		if (!remote_head && option_branch)
+			warning(_("Could not find remote branch %s to clone."),
+				option_branch);
+		else
+			get_fetch_map(remote_head, refspec, &tail, 0);
+	} else
+		get_fetch_map(refs, refspec, &tail, 0);
+
+	if (!option_mirror && !option_single_branch)
 		get_fetch_map(refs, tag_refspec, &tail, 0);
 
 	return local_refs;
@@ -448,6 +471,21 @@ static void write_remote_refs(const struct ref *local_refs)
 	clear_extra_refs();
 }
 
+static void write_followtags(const struct ref *refs, const char *msg)
+{
+	const struct ref *ref;
+	for (ref = refs; ref; ref = ref->next) {
+		if (prefixcmp(ref->name, "refs/tags/"))
+			continue;
+		if (!suffixcmp(ref->name, "^{}"))
+			continue;
+		if (!has_sha1_file(ref->old_sha1))
+			continue;
+		update_ref(msg, ref->name, ref->old_sha1,
+			   NULL, 0, DIE_ON_ERR);
+	}
+}
+
 static int write_one_config(const char *key, const char *value, void *data)
 {
 	return git_config_set_multivar(key, value ? value : "true", "^$", 0);
@@ -478,7 +516,6 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 	struct strbuf key = STRBUF_INIT, value = STRBUF_INIT;
 	struct strbuf branch_top = STRBUF_INIT, reflog_msg = STRBUF_INIT;
 	struct transport *transport = NULL;
-	char *src_ref_prefix = "refs/heads/";
 	int err = 0;
 
 	struct refspec *refspec;
@@ -498,6 +535,9 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 		usage_msg_opt(_("You must specify a repository to clone."),
 			builtin_clone_usage, builtin_clone_options);
 
+	if (option_single_branch == -1)
+		option_single_branch = option_depth ? 1 : 0;
+
 	if (option_mirror)
 		option_bare = 1;
 
@@ -645,6 +685,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 		if (option_depth)
 			transport_set_option(transport, TRANS_OPT_DEPTH,
 					     option_depth);
+		if (option_single_branch)
+			transport_set_option(transport, TRANS_OPT_FOLLOWTAGS, "1");
 
 		transport_set_verbosity(transport, option_verbosity, option_progress);
 
@@ -663,6 +705,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 		clear_extra_refs();
 
 		write_remote_refs(mapped_refs);
+		if (option_single_branch)
+			write_followtags(refs, reflog_msg.buf);
 
 		remote_head = find_ref_by_name(refs, "HEAD");
 		remote_head_points_at =
diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh
index 9bf69e9..7e85c71 100755
--- a/t/t5500-fetch-pack.sh
+++ b/t/t5500-fetch-pack.sh
@@ -114,8 +114,19 @@ pull_to_client 2nd "refs/heads/B" $((64*3))
 
 pull_to_client 3rd "refs/heads/A" $((1*3))
 
+test_expect_success 'single branch clone' '
+	git clone --single-branch "file://$(pwd)/." singlebranch
+'
+
+test_expect_success 'single branch object count' '
+	GIT_DIR=singlebranch/.git git count-objects -v |
+		grep "^in-pack:" > count.singlebranch &&
+	echo "in-pack: 198" >expected &&
+	test_cmp expected count.singlebranch
+'
+
 test_expect_success 'clone shallow' '
-	git clone --depth 2 "file://$(pwd)/." shallow
+	git clone --no-single-branch --depth 2 "file://$(pwd)/." shallow
 '
 
 test_expect_success 'clone shallow object count' '
@@ -248,4 +259,63 @@ test_expect_success 'clone shallow object count' '
 	grep "^count: 52" count.shallow
 '
 
+test_expect_success 'clone shallow without --no-single-branch' '
+	git clone --depth 1 "file://$(pwd)/." shallow2
+'
+
+test_expect_success 'clone shallow object count' '
+	(
+		cd shallow2 &&
+		git count-objects -v
+	) > count.shallow2 &&
+	grep "^in-pack: 6" count.shallow2
+'
+
+test_expect_success 'clone shallow with --branch' '
+	git clone --depth 1 --branch A "file://$(pwd)/." shallow3
+'
+
+test_expect_success 'clone shallow object count' '
+	echo "in-pack: 12" > count3.expected &&
+	GIT_DIR=shallow3/.git git count-objects -v |
+		grep "^in-pack" > count3.actual &&
+	test_cmp count3.expected count3.actual
+'
+
+test_expect_success 'clone shallow with nonexistent --branch' '
+	git clone --depth 1 --branch Z "file://$(pwd)/." shallow4 &&
+	GIT_DIR=shallow4/.git git rev-parse HEAD >actual &&
+	git rev-parse HEAD >expected &&
+	test_cmp expected actual
+'
+
+test_expect_success 'clone shallow with detached HEAD' '
+	git checkout HEAD^ &&
+	git clone --depth 1 "file://$(pwd)/." shallow5 &&
+	git checkout - &&
+	GIT_DIR=shallow5/.git git rev-parse HEAD >actual &&
+	git rev-parse HEAD^ >expected &&
+	test_cmp expected actual
+'
+
+test_expect_success 'shallow clone pulling tags' '
+	git tag -a -m A TAGA1 A &&
+	git tag -a -m B TAGB1 B &&
+	git tag TAGA2 A &&
+	git tag TAGB2 B &&
+	git clone --depth 1 "file://$(pwd)/." shallow6 &&
+
+	cat >taglist.expected <<\EOF &&
+TAGB1
+TAGB2
+EOF
+	GIT_DIR=shallow6/.git git tag -l >taglist.actual &&
+	test_cmp taglist.expected taglist.actual &&
+
+	echo "in-pack: 7" > count6.expected &&
+	GIT_DIR=shallow6/.git git count-objects -v |
+		grep "^in-pack" > count6.actual &&
+	test_cmp count6.expected count6.actual
+'
+
 test_done
-- 
1.7.8.36.g69ee2

^ permalink raw reply related

* Re: [PATCH 1/5] run-command: optionally kill children on exit
From: Jeff King @ 2012-01-07 14:41 UTC (permalink / raw)
  To: Clemens Buchacher
  Cc: Junio C Hamano, git, Jonathan Nieder, Erik Faye-Lund,
	Ilari Liusvaara, Nguyễn Thái Ngọc Duy
In-Reply-To: <1325936567-3136-2-git-send-email-drizzd@aon.at>

On Sat, Jan 07, 2012 at 12:42:43PM +0100, Clemens Buchacher wrote:

> Signed-off-by: Clemens Buchacher <drizzd@aon.at>
> ---
> 
> Not sure if I can sign off without your sign-off. Should I have
> replaced this with Acked-by?

Sorry, I usually sign-off when I sent to the list. But:

Signed-off-by: Jeff King <peff@peff.net>

for this and the other patch in this series.

As for whether you can sign-off, I think it is OK in this case. You are
basically signing off on the "Certificate of Origin" found in
SubmittingPatches. I think you are covered under (b), which is that to
the best of your knowledge it is based on open source work (i.e., even
though I didn't sign off explicitly, it is pretty obvious that this is
meant to be open source). But it's nicer to be explicit.

-Peff

^ permalink raw reply

* Re: [PATCH v3] Limit refs to fetch to minimum in shallow clones
From: Nguyen Thai Ngoc Duy @ 2012-01-07 14:16 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Shawn O. Pearce
In-Reply-To: <7vfwfsllny.fsf@alter.siamese.dyndns.org>

2012/1/7 Junio C Hamano <gitster@pobox.com>:
> My first reaction after reading "is implied by default" was "Huh? didn't
> we just read these kick in only when --depth is given?" and I had to read
> it again. Here is my attempt to rephrase it.
>
>        Clone only the history leading to the tip of a single branch,
>        either specified by the `--branch` option or the primary branch
>        remote's `HEAD` points at. When creating a shallow clone with the
>        `--depth` option, this is the default, unless `--no-single-branch`
>        is given to fetch the histories near the tips of all branches.
>
>        Currently this option only works when creating a shallow clone and
>        does not have any effect without the `--depth` option.
>
> We might want to later enhance this to work also with a full-depth clone
> that tracks only one branch, and the above phrasing would make it clear.

Interesting. Yes that's another possibility.

>> +             if (!option_branch)
>> +                     remote_head = guess_remote_head(head, refs, 0);
>> +             else {
>> +                     struct strbuf sb = STRBUF_INIT;
>> +                     strbuf_addstr(&sb, src_ref_prefix);
>> +                     strbuf_addstr(&sb, option_branch);
>> +                     remote_head = find_ref_by_name(refs, sb.buf);
>> +                     strbuf_release(&sb);
>> +             }
>> +
>> +             if (!remote_head)
>> +                     die(_("Remote branch \"%s\" not found. Nothing to clone.\n"
>> +                           "Try --no-single-branch to fetch all refs."),
>> +                         option_branch ? option_branch : "HEAD");
>
> Switching upon option_branch to tweak the message is a good idea, but
> strictly speaking, we would hit this die() when guess_remote_head() does
> not find where HEAD points at because it is detached, and in that case,
> the error is not "Nothing to clone", but "We couldn't tell which branch
> you meant to limit this cloning to".

Yeah. And in detached case without --branch, we probably should not
say anything.

>> @@ -642,9 +679,12 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
>>
>>               transport_set_option(transport, TRANS_OPT_KEEP, "yes");
>>
>> -             if (option_depth)
>> +             if (option_depth) {
>>                       transport_set_option(transport, TRANS_OPT_DEPTH,
>>                                            option_depth);
>> +                     transport_set_option(transport, TRANS_OPT_FOLLOWTAGS,
>> +                                          option_single_branch ? "1" : NULL);
>
> Curious. Does anybody set FOLLOWTAGS to the transport by default becore we
> come here (just asking)?

No, I just hate another "if (option_single_branch)", which indents the
call one more time. Always setting it to "1" in this case should
probably be OK too. I'm just not sure if upload-pack realizes all tags
are requested so include-tag extension means nothing, or it does extra
work for no gain.
-- 
Duy

^ permalink raw reply

* Re: Aborting "git commit --interactive" discards updates to index
From: demerphq @ 2012-01-07 14:16 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Ævar Arnfjörð
In-Reply-To: <7vvcoogkw8.fsf@alter.siamese.dyndns.org>

On 7 January 2012 06:08, Junio C Hamano <gitster@pobox.com> wrote:
> demerphq <demerphq@gmail.com> writes:
>
>> On 27 June 2011 17:59, Junio C Hamano <gitster@pobox.com> wrote:
>>> The latest feature release Git 1.7.6 is available at the usual
>>> places:
>>>
>>>  http://www.kernel.org/pub/software/scm/git/
>> [snip]
>>>  * Aborting "git commit --interactive" discards updates to the index
>>>   made during the interactive session.
>>
>> Hi, I am wondering why this change was made?
>
> I wasn't directly involved in this particular part of the design of what
> should happen to the index when a commit is aborted, so I would be a bad
> person to give you the first answer, but let's try.
>
> If a "commit" session is aborted, it is logical to revert whatever has
> been done inside that session as a single logical unit, so I do not
> particularly find the current behaviour so confusing. It might even make
> more sense if we update "commit -i" and "commit -a" to also revert the
> index modification when the command is aborted for consistency.
>
> You are welcome to rehash the age old discussion, though. Personally I do
> not care very deeply either way. I would never use "commit --interactive"
> myself, and I would not encourage others to use it, either, even if we do
> not worry about the behaviour when a commit is aborted.

If I were to provide a patch to make this behavior configurable would
you have any objections? I personally much prefer the old behaviour. I
want it to leave the stuff in my index.

>
> One thread of interest (there are others, as this change was rerolled at
> least a few times) may be
>
>    http://thread.gmane.org/gmane.comp.version-control.git/173033/focus=173035

Thanks.

> Having said all that,...
>
>> .... I am writing this after spending about 45 minutes showing a
>> colleague how to use git commit --interactive, when we realized that
>> we had forgotten to add a file....
>
> ... if your partial commit is so complex that you need to spend 45 minutes
> to sift what to be commited and what to be left out, you are much better

I was showing a colleague how to use the features it provides on a
large patch where the committer wanted to keep various bits and not
keep others.

> off to run "git add -i" to prepare the index, "git stash save -k" to check
> out what is to be committed (and stash away what are to be left out) so
> that you can make sure what you are committing is what you thought are
> committing (by asking "git diff" and "make test" for example), and after

Isnt this what the diff option in commit interactive is for?
Personally I tend to review patches in detail before I push them, not
necessarily before I commit them.

> convincing yourself that you made a good state in the index, make a commit
> with "git commit" (without any other arguments) and conclude it with "git
> stash pop" to recover the changes that you decided to leave out.

I personally have never had an issue with git commit --interactive so
this procedure seems really convoluted to me, and a lot harder to
teach to a colleague than "use git commit --interactive". Is there a
real problem it solves?

> "commit --interactive" robs me from that crucial "verification" step, and
> that is why I wouldn't be a user or an advocate of this "misfeature".

I understand. But that is a workflow directed to statically testable
library code. Our workflow doesn't really depend on a "make test"
phase. Also, if I calling git commit --interactive (or git add -i),
then I am as confident my code works as I can be, and the reason I am
doing an interactive step is for instance to edit out debug lines, or
separate out whitespace changes from code changes, or to break my
change set into several logical groups.

> By the way, why did you draw Ævar into this discussion? I do not think he
> was involved in any way with the design or implementation of this command.

He is a git hacker, and is a friend and colleague. We both work for a
largish dotcom which uses git as our primary version control and we
have collaborated on a tool I wrote to use git to manage our rollout
processes. So when something git comes up it is natural to me to CC
him.

cheers,
Yves

-- 
perl -Mre=debug -e "/just|another|perl|hacker/"

^ permalink raw reply

* Re: [PATCH 1/5] run-command: optionally kill children on exit
From: Erik Faye-Lund @ 2012-01-07 12:45 UTC (permalink / raw)
  To: Clemens Buchacher
  Cc: Junio C Hamano, git, Jeff King, Jonathan Nieder, Ilari Liusvaara,
	Nguyễn Thái Ngọc Duy
In-Reply-To: <1325936567-3136-2-git-send-email-drizzd@aon.at>

On Sat, Jan 7, 2012 at 12:42 PM, Clemens Buchacher <drizzd@aon.at> wrote:
> +static void cleanup_children(int sig)
> +{
> +       while (children_to_clean) {
> +               struct child_to_clean *p = children_to_clean;
> +               children_to_clean = p->next;
> +               kill(p->pid, sig);
> +               free(p);
> +       }
> +}
> +
> +static void cleanup_children_on_signal(int sig)
> +{
> +       cleanup_children(sig);
> +       sigchain_pop(sig);
> +       raise(sig);
> +}
> +

Our Windows implementation of kill (mingw_kill in compat/mingw.c) only
supports SIGKILL, so propagating other signals to child-processes will
fail with EINVAL. That being said, Windows' support for signals is
severely limited, but I'm not entirely sure which ones can be
generated in this case.

> @@ -312,6 +375,7 @@ fail_pipe:
>                cmd->pid = -1;
>        }
>        close(notify_pipe[0]);
> +
>  }
>  #else
>  {

This hunk is probably unintentional...

^ permalink raw reply

* [PATCH] credentials: unable to connect to cache daemon
From: Clemens Buchacher @ 2012-01-07 11:54 UTC (permalink / raw)
  To: Jeff King
  Cc: Junio C Hamano, git, Jonathan Nieder, Erik Faye-Lund,
	Ilari Liusvaara, Nguyễn Thái Ngọc Duy
In-Reply-To: <20120106223215.GA13106@sigill.intra.peff.net>

Error out if we just spawned the daemon and yet we cannot connect.

And always release the string buffer.

Signed-off-by: Clemens Buchacher <drizzd@aon.at>
---

Hi Jeff,

I wrote this while debugging why t0301-credential-cache.sh failed after
I enabled cleanup_children by default. This error condition turned out
not to be the problem, and this patch would not have helped in debugging
this case. But I think it makes sense anyways.

 credential-cache.c |    7 +++----
 1 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/credential-cache.c b/credential-cache.c
index dc98372..8f25c06 100644
--- a/credential-cache.c
+++ b/credential-cache.c
@@ -71,11 +71,10 @@ static void do_cache(const char *socket, const char *action, int timeout,
 			die_errno("unable to relay credential");
 	}
 
-	if (!send_request(socket, &buf))
-		return;
-	if (flags & FLAG_SPAWN) {
+	if (send_request(socket, &buf) < 0 && flags & FLAG_SPAWN) {
 		spawn_daemon(socket);
-		send_request(socket, &buf);
+		if (send_request(socket, &buf) < 0)
+			die_errno("unable to connect to cache daemon");
 	}
 	strbuf_release(&buf);
 }
-- 
1.7.8

^ permalink raw reply related

* Re: [PATCH 1/2] daemon: add tests
From: Clemens Buchacher @ 2012-01-07 11:46 UTC (permalink / raw)
  To: Jakub Narebski
  Cc: Jeff King, Junio C Hamano, git, Jonathan Nieder, Erik Faye-Lund,
	Ilari Liusvaara, Nguyễn Thái Ngọc Duy
In-Reply-To: <201201070035.52581.jnareb@gmail.com>

On Sat, Jan 07, 2012 at 12:35:50AM +0100, Jakub Narebski wrote:
> > 
> > We could probably add a "--notify-when-ready" option to git-daemon to
> > do something similar.
> 
> What would git-daemon do what it is ready?  Write to socket, raise signal,
> print to STDOUT / STDERR?

Please have a look at my "git-daemon: produce output when ready" patch.
After opening the socket, git-daemon --verbose writes "Ready to rumble"
to stderr.

^ 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