[PATCH] help: correct behavior for is_executable on Windows
The previous implementation said that the filesystem information on Windows is not reliable to determine whether a file is executable. To find gather this information it was peeking into the first two bytes of a file to see whether it looks executable. Apart from the fact that on Windows executables are usually defined as such by their extension it lead to slow opening of help file in some situations. When you have virus scanner running calling open on an executable file is a potentially expensive operation. See the following measurements (in seconds) for example. With virus scanner running (coldcache): $ ./a.exe /libexec/git-core/ before open (git-add.exe): 0.00 after open (git-add.exe): 0.412873 before open (git-annotate.exe): 0.000175 after open (git-annotate.exe): 0.397925 before open (git-apply.exe): 0.000243 after open (git-apply.exe): 0.36 before open (git-archive.exe): 0.000147 after open (git-archive.exe): 0.397783 before open (git-bisect--helper.exe): 0.000160 after open (git-bisect--helper.exe): 0.397700 before open (git-blame.exe): 0.000160 after open (git-blame.exe): 0.399136 ... With virus scanner running (hotcache): $ ./a.exe /libexec/git-core/ before open (git-add.exe): 0.00 after open (git-add.exe): 0.000325 before open (git-annotate.exe): 0.000229 after open (git-annotate.exe): 0.000177 before open (git-apply.exe): 0.000167 after open (git-apply.exe): 0.000150 before open (git-archive.exe): 0.000154 after open (git-archive.exe): 0.000156 before open (git-bisect--helper.exe): 0.000132 after open (git-bisect--helper.exe): 0.000180 before open (git-blame.exe): 0.000718 after open (git-blame.exe): 0.000724 ... This test did just list the given directory and open() each file in it. With this patch I get: $ time git help git Launching default browser to display HTML ... real0m8.723s user0m0.000s sys 0m0.000s and without $ time git help git Launching default browser to display HTML ... real1m37.734s user0m0.000s sys 0m0.031s both tests with cold cache and giving the machine some time to settle down after restart. Signed-off-by: Heiko Voigt --- help.c | 15 --- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/help.c b/help.c index 662349d..b41fa21 100644 --- a/help.c +++ b/help.c @@ -103,10 +103,19 @@ static int is_executable(const char *name) return 0; #if defined(WIN32) || defined(__CYGWIN__) + /* On Windows we cannot use the executable bit. The executable +* state is determined by extension only. We do this first +* because with virus scanners opening an executeable for +* reading is potentially expensive. +*/ + if (has_extension(name, ".exe")) + return S_IXUSR; + #if defined(__CYGWIN__) if ((st.st_mode & S_IXUSR) == 0) #endif -{ /* cannot trust the executable bit, peek into the file instead */ +{ /* now that we know it does not have an executable extension, + peek into the file instead */ char buf[3] = { 0 }; int n; int fd = open(name, O_RDONLY); @@ -114,8 +123,8 @@ if ((st.st_mode & S_IXUSR) == 0) if (fd >= 0) { n = read(fd, buf, 2); if (n == 2) - /* DOS executables start with "MZ" */ - if (!strcmp(buf, "#!") || !strcmp(buf, "MZ")) + /* look for a she-bang */ + if (!strcmp(buf, "#!")) st.st_mode |= S_IXUSR; close(fd); } -- 1.7.12.rc2.10.gaf2525e -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Porting git to HP NonStop
Am 10.08.2012 18:27, schrieb Shawn Pearce: > There is no need to define your own mmap(). Define NO_MMAP=1 in the > Makefile. Git already has its own fake mmap and knows how to write it > back to disk when making changes. Or better to say: the fake mmap has functionality that is sufficient for git. In particular, it does *not* write back changes to disk (it supports only MAP_PRIVATE), and the mapped area does not change if the file is changed by a third party. -- Hannes -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Bringing a bit more sanity to $GIT_DIR/objects/info/alternates?
Junio C Hamano wrote: >Some ideas: > >- Make "clone --reference" without "-s" not to borrow from the > reference repository. (...) Generalize: Introduce volatile alternate object stores. Commands like (remote) fetch, repack, gc will copy desired objects they see there. That allows pruneable alternates if people want them: Make every borrowing repo also borrow from a companion volatile store. To prune some shared objects: Move them from the alternate to the volatile. Repack or gc all borrowing repos. Empty the volatile alternate. Similar to detach from one alternate repo while keeping others: gc with the to-be-dropped alternate as a volatile. Also it gives a simple way to try to repair a repo with missing objects, if you have some other repositories which might have the objects: Repack with the other repositories as volatile alternates. BTW, if a wanted object disappears from the volatile alternate while fetch is running, fetch should get it from the remote after all. >- Make the distinction between a regular repository and an object > store that is meant to be used for object sharing stronger. > > Perhaps a configuration item "core.objectstore = readonly" can > be introduced, and we forbid "clone -s" from pointing at a > repository without such a configuration. We also forbid object > pruning operations such as "gc" and "repack" from being run in > a repository marked as such. I hope Michael's "append-only"/"donor" is feasible instead. In which case safer gc/repack are needed, like you outline: > It may be necessary to allow some special kind of repacking of > such a "readonly" object store, in order to reduce the number > of packfiles (and get rid of loose object files); it needs to > be implemented carefully not to lose any object, regardless of > local reachability. And it needs to be default behavior in such stores, so users won't need don't-shoot-myself-in-foot options. >- It might not be a bad idea to have a dedicated new command to > help users manage alternates ("git alternates"?); obviously > this will be one of its subcommand "git alternates detach" if > we go that route. "git object-store -- manage alternates & object stores"? >- Or just an entry in the documentation is sufficient? Better doc would be useful anyway, and this command gives a place to put it:-) I had no idea alternates were intended to be read-only, but that does explain some seeming defects I'd wondered about. > - When you have two or more repositories that do not share objects, >you may want to rearrange things so that they share their objects >from a single common object store. > >There is no direct UI to do this, as far as I know. You can >obviously create a new bare repository, push there from all >of these repositories, and then borrow from there, e.g. > > git --bare init shared.git && > for r in a.git b.git c.git ... > do > ( > cd "$r" && > git push ../shared.git "refs/*:refs/remotes/$r/*" && > echo ../../../shared.git/objects >.git/objects/info/alternates > ) > done > >And then repack shared.git once. ...and finally gc the other repositories. The refs/remotes/$r/ namespace becomes misleading if the user renames or copies the corresponding Git repository, and then cleverly does something to the shared repo and the repo (if any) in directory $r. I suggest refs/remotes/$unique_number/ and note $unique_number somewhere in the borrowing repo. If someone insists on being clever, this may force them to read up on what they're doing first. Or store no refs, since the shared repo shouldn't lose objects anyway. If we're sure objects won't be lost: Create a proper remote with the shared repo. That way the user can push into it once in a while, and he can configure just which refs should be shared. > >Some ideas: > >- (obvious: give a canned command to do the above, perhaps then > set the core.objectstore=readonly in the resuting shared.git) That's getting closer to 'bzr init-repository': One dir with the shared repo and all borrowing repositories. A simple model which Git can track and the user need not think further about. This way, git clone/init of a new repo in this dir can learn to notice and use the shared repo. We can also have a command (git object-store?) to maintain the repository collection, since Git knows where to find them all: Push from all repos into the shared repo, gc all repos, even prune unused objects from the shared repo - after imlementing sufficient paranoia. > - When you have one object store and a repository that does not yet >borrow from it, you may want to make the repository borrow from >the object store. Obviously you can run "echo" like the sample >script in the previous item above, but it is not obvious how to >perform th
Re: Git hangs on clone
I should add to the facts that: - git version: git version 1.7.11.2 - Happens only when using protocols git:// and have seen it with https:// too, but never with http:// - Saw a similar issue here: http://code.google.com/p/msysgit/issues/detail?id=361 On 11 August 2012 04:48, Paul Alesius wrote: > 80 out of 100 times git will hang indefinitely during a clone operation. > Here's the state of things during the hangs: > > > --- scenario 1: > remote: Counting objects: 306395, done. > remote: Compressing objects: 100% (47753/47753), done. > remote: Total 306395 (delta 259044), reused 305469 (delta 258264) > Receiving objects: 100% (306395/306395), 207.20 MiB | 5.80 MiB/s, done. > Resolving deltas: 100% (259044/259044), done. > --- ps aux | grep git: > build28122 0.1 0.0 126032 2092 pts/1Sl+ 04:19 0:00 git clone > git://git.gnome.org/gtk+ > -- backtrace for scenario 1: > (gdb) bt > #0 0x003c9ee08e60 in pthread_join (threadid=47144800229120, > thread_return=thread_return@entry=0x7fff19edc928) at pthread_join.c:93 > #1 0x004cb6ab in finish_async (async=async@entry=0x7fff19edca00) at > run-command.c:739 > #2 0x00428318 in get_pack (pack_lockfile=0x121df80, xd=0x121dfc0) > at builtin/fetch-pack.c:773 > #3 do_fetch_pack (pack_lockfile=0x121df80, match=0x125e0a0, nr_match=544, > orig_ref=, fd=0x121dfc0) at builtin/fetch-pack.c:835 > #4 fetch_pack (my_args=my_args@entry=0x7fff19edd1b0, fd=fd@entry=0x121dfc0, > conn=, ref=, dest=dest@entry=0x1217e70 > "git://git.gnome.org/gtk+", > nr_heads=nr_heads@entry=544, heads=heads@entry=0x125e0a0, > pack_lockfile=pack_lockfile@entry=0x121df80) at builtin/fetch-pack.c:1090 > #5 0x004de08e in fetch_refs_via_pack (transport=0x121df20, > nr_heads=544, to_fetch=0x125c880) at transport.c:549 > #6 0x004e0472 in transport_fetch_refs > (transport=transport@entry=0x121df20, refs=refs@entry=0x123d3c0) at > transport.c:1167 > #7 0x0041cbce in cmd_clone (argc=, argv= out>, prefix=) at builtin/clone.c:859 > #8 0x004057d8 in run_builtin (argv=0x7fff19edd900, argc=2, > p=0x74a040) at git.c:308 > #9 handle_internal_command (argc=2, argv=0x7fff19edd900) at git.c:468 > #10 0x00404be2 in run_argv (argv=0x7fff19edd790, > argcp=0x7fff19edd79c) at git.c:514 > #11 main (argc=2, argv=0x7fff19edd900) at git.c:589 > -- > > > > > -- scenario 2: > remote: Counting objects: 306395, done. > remote: Compressing objects: 100% (47753/47753), done. > Receiving objects: 99% (303332/306395), 205.18 MiB | 452 KiB/s > --- ps aux | grep git: > build28247 0.5 0.0 126032 2088 pts/1Sl+ 04:30 0:00 git clone > git://git.gnome.org/gtk+ > build28249 8.4 0.3 144908 30480 pts/1S+ 04:30 0:12 git > index-pack --stdin -v --fix-thin --keep=fetch-pack 28247 on mydomain > -- backtrace for scenario 1: > #0 0x003c9ee0e0ad in read () at ../sysdeps/unix/syscall-template.S:82 > #1 0x004ea29f in read (__nbytes=46, __buf=0x7fffeb4d8cc0, __fd=7) > at /usr/include/bits/unistd.h:45 > #2 xread (fd=fd@entry=7, buf=buf@entry=0x7fffeb4d8cc0, len=len@entry=46) at > wrapper.c:142 > #3 0x004ea38b in read_in_full (fd=7, buf=buf@entry=0x7fffeb4d8cc0, > count=count@entry=46) at wrapper.c:171 > #4 0x004ad78c in index_pack_lockfile (ip_out=) at > pack-write.c:298 > #5 0x004285d4 in get_pack (pack_lockfile=0x1928f80, xd=0x1928fc0) > at builtin/fetch-pack.c:767 > #6 do_fetch_pack (pack_lockfile=0x1928f80, match=0x19690a0, nr_match=544, > orig_ref=, fd=0x1928fc0) at builtin/fetch-pack.c:835 > #7 fetch_pack (my_args=my_args@entry=0x7fffeb4da580, fd=fd@entry=0x1928fc0, > conn=, ref=, dest=dest@entry=0x1922e70 > "git://git.gnome.org/gtk+", > nr_heads=nr_heads@entry=544, heads=heads@entry=0x19690a0, > pack_lockfile=pack_lockfile@entry=0x1928f80) at builtin/fetch-pack.c:1090 > #8 0x004de08e in fetch_refs_via_pack (transport=0x1928f20, > nr_heads=544, to_fetch=0x1967880) at transport.c:549 > #9 0x004e0472 in transport_fetch_refs > (transport=transport@entry=0x1928f20, refs=refs@entry=0x19483c0) at > transport.c:1167 > #10 0x0041cbce in cmd_clone (argc=, argv= out>, prefix=) at builtin/clone.c:859 > #11 0x004057d8 in run_builtin (argv=0x7fffeb4dacd0, argc=2, > p=0x74a040) at git.c:308 > #12 handle_internal_command (argc=2, argv=0x7fffeb4dacd0) at git.c:468 > #13 0x00404be2 in run_argv (argv=0x7fffeb4dab60, > argcp=0x7fffeb4dab6c) at git.c:514 > #14 main (argc=2, argv=0x7fffeb4dacd0) at git.c:589 > -- > > > > -- facts: > - Happens on multiple machines on this LAN, which made me believe it's the > NAT router. > - Happens when using any repository. > - There's nothing filtering egress ports (Other than the NAT) > - Kernel 3(?) to 3.5 which I run currently > - I often see it hang at _
Re: [msysGit] Feature request: Add url/dir parameter to git svn info
On Sat, Aug 11, 2012 at 12:51 PM, wrote: > Hi > > Why i cannot use git svn info outside of git folder ? This command miss an > url/dir parameter. Can somebody add such function to this command ? It's for > batch scripts etc > This isn't Windows specific, so this feature-request is more suited for the main Git mailing list. Adding CC. -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] i18n: mark progress strings for translation
Signed-off-by: Nguyễn Thái Ngọc Duy --- I know it's late in the cycle so let's queue it for the next one before I forget it. I'm after the "done\n" in index-pack but we should also make it possible to translate units (especially "bytes" which is plural). There are ellipsis elsewhere in this file but I don't think it's worth translating. progress.c | 15 --- 1 tập tin đã bị thay đổi, 8 được thêm vào(+), 7 bị xóa(-) diff --git a/progress.c b/progress.c index 3971f49..b69d657 100644 --- a/progress.c +++ b/progress.c @@ -9,6 +9,7 @@ */ #include "git-compat-util.h" +#include "gettext.h" #include "progress.h" #define TP_IDX_MAX 8 @@ -117,29 +118,29 @@ static void throughput_string(struct throughput *tp, off_t total, { int l = sizeof(tp->display); if (total > 1 << 30) { - l -= snprintf(tp->display, l, ", %u.%2.2u GiB", + l -= snprintf(tp->display, l, _(", %u.%2.2u GiB"), (int)(total >> 30), (int)(total & ((1 << 30) - 1)) / 10737419); } else if (total > 1 << 20) { int x = total + 5243; /* for rounding */ - l -= snprintf(tp->display, l, ", %u.%2.2u MiB", + l -= snprintf(tp->display, l, _(", %u.%2.2u MiB"), x >> 20, ((x & ((1 << 20) - 1)) * 100) >> 20); } else if (total > 1 << 10) { int x = total + 5; /* for rounding */ - l -= snprintf(tp->display, l, ", %u.%2.2u KiB", + l -= snprintf(tp->display, l, _(", %u.%2.2u KiB"), x >> 10, ((x & ((1 << 10) - 1)) * 100) >> 10); } else { - l -= snprintf(tp->display, l, ", %u bytes", (int)total); + l -= snprintf(tp->display, l, _(", %u bytes"), (int)total); } if (rate > 1 << 10) { int x = rate + 5; /* for rounding */ snprintf(tp->display + sizeof(tp->display) - l, l, -" | %u.%2.2u MiB/s", +_(" | %u.%2.2u MiB/s"), x >> 10, ((x & ((1 << 10) - 1)) * 100) >> 10); } else if (rate) snprintf(tp->display + sizeof(tp->display) - l, l, -" | %u KiB/s", rate); +_(" | %u KiB/s"), rate); } void display_throughput(struct progress *progress, off_t total) @@ -236,7 +237,7 @@ struct progress *start_progress(const char *title, unsigned total) void stop_progress(struct progress **p_progress) { - stop_progress_msg(p_progress, "done"); + stop_progress_msg(p_progress, _("done")); } void stop_progress_msg(struct progress **p_progress, const char *msg) -- 1.7.12.rc2.18.g61b472e -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Git hangs on clone
Difficult that it is a git problem. It is better to trace the network communication, a wireshark trace for example. But it is probably a firewall or UTM, if you have, issue. Best 2012/8/11, Paul Alesius : > I should add to the facts that: > > > - git version: git version 1.7.11.2 > - Happens only when using protocols git:// and have seen it with > https:// too, but never with http:// > - Saw a similar issue here: > http://code.google.com/p/msysgit/issues/detail?id=361 > > > On 11 August 2012 04:48, Paul Alesius wrote: >> 80 out of 100 times git will hang indefinitely during a clone operation. >> Here's the state of things during the hangs: >> >> >> --- scenario 1: >> remote: Counting objects: 306395, done. >> remote: Compressing objects: 100% (47753/47753), done. >> remote: Total 306395 (delta 259044), reused 305469 (delta 258264) >> Receiving objects: 100% (306395/306395), 207.20 MiB | 5.80 MiB/s, done. >> Resolving deltas: 100% (259044/259044), done. >> --- ps aux | grep git: >> build28122 0.1 0.0 126032 2092 pts/1Sl+ 04:19 0:00 git >> clone >> git://git.gnome.org/gtk+ >> -- backtrace for scenario 1: >> (gdb) bt >> #0 0x003c9ee08e60 in pthread_join (threadid=47144800229120, >> thread_return=thread_return@entry=0x7fff19edc928) at pthread_join.c:93 >> #1 0x004cb6ab in finish_async (async=async@entry=0x7fff19edca00) >> at >> run-command.c:739 >> #2 0x00428318 in get_pack (pack_lockfile=0x121df80, >> xd=0x121dfc0) >> at builtin/fetch-pack.c:773 >> #3 do_fetch_pack (pack_lockfile=0x121df80, match=0x125e0a0, >> nr_match=544, >> orig_ref=, fd=0x121dfc0) at builtin/fetch-pack.c:835 >> #4 fetch_pack (my_args=my_args@entry=0x7fff19edd1b0, >> fd=fd@entry=0x121dfc0, >> conn=, ref=, dest=dest@entry=0x1217e70 >> "git://git.gnome.org/gtk+", >> nr_heads=nr_heads@entry=544, heads=heads@entry=0x125e0a0, >> pack_lockfile=pack_lockfile@entry=0x121df80) at builtin/fetch-pack.c:1090 >> #5 0x004de08e in fetch_refs_via_pack (transport=0x121df20, >> nr_heads=544, to_fetch=0x125c880) at transport.c:549 >> #6 0x004e0472 in transport_fetch_refs >> (transport=transport@entry=0x121df20, refs=refs@entry=0x123d3c0) at >> transport.c:1167 >> #7 0x0041cbce in cmd_clone (argc=, >> argv=> out>, prefix=) at builtin/clone.c:859 >> #8 0x004057d8 in run_builtin (argv=0x7fff19edd900, argc=2, >> p=0x74a040) at git.c:308 >> #9 handle_internal_command (argc=2, argv=0x7fff19edd900) at git.c:468 >> #10 0x00404be2 in run_argv (argv=0x7fff19edd790, >> argcp=0x7fff19edd79c) at git.c:514 >> #11 main (argc=2, argv=0x7fff19edd900) at git.c:589 >> -- >> >> >> >> >> -- scenario 2: >> remote: Counting objects: 306395, done. >> remote: Compressing objects: 100% (47753/47753), done. >> Receiving objects: 99% (303332/306395), 205.18 MiB | 452 KiB/s >> --- ps aux | grep git: >> build28247 0.5 0.0 126032 2088 pts/1Sl+ 04:30 0:00 git >> clone >> git://git.gnome.org/gtk+ >> build28249 8.4 0.3 144908 30480 pts/1S+ 04:30 0:12 git >> index-pack --stdin -v --fix-thin --keep=fetch-pack 28247 on mydomain >> -- backtrace for scenario 1: >> #0 0x003c9ee0e0ad in read () at >> ../sysdeps/unix/syscall-template.S:82 >> #1 0x004ea29f in read (__nbytes=46, __buf=0x7fffeb4d8cc0, >> __fd=7) >> at /usr/include/bits/unistd.h:45 >> #2 xread (fd=fd@entry=7, buf=buf@entry=0x7fffeb4d8cc0, len=len@entry=46) >> at >> wrapper.c:142 >> #3 0x004ea38b in read_in_full (fd=7, >> buf=buf@entry=0x7fffeb4d8cc0, >> count=count@entry=46) at wrapper.c:171 >> #4 0x004ad78c in index_pack_lockfile (ip_out=) at >> pack-write.c:298 >> #5 0x004285d4 in get_pack (pack_lockfile=0x1928f80, >> xd=0x1928fc0) >> at builtin/fetch-pack.c:767 >> #6 do_fetch_pack (pack_lockfile=0x1928f80, match=0x19690a0, >> nr_match=544, >> orig_ref=, fd=0x1928fc0) at builtin/fetch-pack.c:835 >> #7 fetch_pack (my_args=my_args@entry=0x7fffeb4da580, >> fd=fd@entry=0x1928fc0, >> conn=, ref=, dest=dest@entry=0x1922e70 >> "git://git.gnome.org/gtk+", >> nr_heads=nr_heads@entry=544, heads=heads@entry=0x19690a0, >> pack_lockfile=pack_lockfile@entry=0x1928f80) at builtin/fetch-pack.c:1090 >> #8 0x004de08e in fetch_refs_via_pack (transport=0x1928f20, >> nr_heads=544, to_fetch=0x1967880) at transport.c:549 >> #9 0x004e0472 in transport_fetch_refs >> (transport=transport@entry=0x1928f20, refs=refs@entry=0x19483c0) at >> transport.c:1167 >> #10 0x0041cbce in cmd_clone (argc=, >> argv=> out>, prefix=) at builtin/clone.c:859 >> #11 0x004057d8 in run_builtin (argv=0x7fffeb4dacd0, argc=2, >> p=0x74a040) at git.c:308 >> #12 handle_internal_command (argc=2, argv=0x7fffeb4dacd0) at git.c:468 >> #13 0x00404be2 in run_argv (argv=0x7fffeb4dab60, >> argcp=0x7fffeb4dab6c) at git.c:514 >> #14 main (argc=2, argv=0x
Re: Localization: Timestamps get wrong if using different locales
Hello! What I am doing is: invoking a bash script that does the git add ${i##$TXPATH/}/strings.xml git commit --author="$AUTHOR" ${i##$TXPATH\/}/strings.xml -m "l10n: $LNAME update" after a user confirmation. IIUC setting LANGUAGE=en at the top of this script _did_ help. So I run everything with german locale for reproducing this. On 05.08.2012 22:47, Junio C Hamano wrote: Christoph Miebach writes: Running this commands locally (german locale) lead to some wrong dates for the patches upstream. git format-patch -o patches origin What does "git show -s --pretty=fuller HEAD" give you at this point? This is to check what kind of timestamps are stored in the original commit objects. See pretty_fuller.txt And what does "grep '^Date: ' patches/0001-*" show you at this point? This is to see if the problem is at the "format-patch" step. See date_grep.txt git send-email --compose --no-chain-reply-to --to s...@address.com --suppress-cc=author patches/0001-l10n-Turkish-update.patch And what does "grep '^Date: '" for the message that is received by recipients show at this step? They cannot be The local Date: Sat, 4 Aug 2012 became Wed, 8 Dec 2004 as these two do not even have times and zones. It should read something like Date: Sun, 05 Aug 2012 13:39:12 -0700 or something. It was a complete line. I just did not copy all of it, for I thought I already pointed out the problem. The recipient uses en_CA.UTF-8 and guesses: Date: 12-08-05 06:10 PM it is Y-M-D, but git thinks it's M-Y-D Also "Date" on which message do you see your problem with? The one that is created with --compose? Or the one that was originally produced by format-patch and then sent? Or both? git log should show the translators name ($AUTHOR in the git commit line) Sorry for the late (and probably still incomplete) reply. I can provide a complete example or send a patch to a dummy project if you prefer some time next week, I hope. Regards Christoph commit b6f59b4a61f1bd203bb0d449dabac7b16351e2e1 Author: Christoph Miebach AuthorDate: Mon Aug 6 00:07:54 2012 +0200 Commit: Christoph Miebach CommitDate: Mon Aug 6 00:07:54 2012 +0200 l10n: German update Date: Mon, 6 Aug 2012 00:07:54 +0200
[PATCH 0/5] git p4: fix branch detection with --use-client-spec
matt...@korich.net wrote on Fri, 10 Aug 2012 12:14 -0700: > Using git p4 on git version 1.7.12.rc2 has path issues. Standard > clone/sync ops apparently place detected master and branches on > independent and parallel directory structures instead of git branches. > See http://stackoverflow.com/q/11893688/1588831 for a full demo of the > problem. Thank you for the detailed report. It is a bug in 1.7.12-rc2. This series fixes it, on top of origin/master. The crux of the matter is that files are mapped into the wrong locations in git when both --use-client-spec and --branch-detection are enabled. Pete Wyckoff (5): git p4 test: move client_view() function to library git p4 test: add broken --use-client-spec --detect-branches tests git p4: set self.branchPrefixes in initialization git p4: do wildcard decoding in stripRepoPath git p4: make branch detection work with --use-client-spec git-p4.py | 75 +++-- t/lib-git-p4.sh | 18 ++ t/t9801-git-p4-branch.sh | 77 +++ t/t9809-git-p4-client-view.sh | 17 -- 4 files changed, 146 insertions(+), 41 deletions(-) -- 1.7.12.rc2.24.gc304662 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/5] git p4 test: move client_view() function to library
This code will be useful in --detect-branches --use-client-spec tests. Signed-off-by: Pete Wyckoff --- t/lib-git-p4.sh | 18 ++ t/t9809-git-p4-client-view.sh | 17 - 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/t/lib-git-p4.sh b/t/lib-git-p4.sh index 2d753ab..5c952d6 100644 --- a/t/lib-git-p4.sh +++ b/t/lib-git-p4.sh @@ -115,3 +115,21 @@ marshal_dump() { EOF "$PYTHON_PATH" "$TRASH_DIRECTORY/marshal-dump.py" } + +# +# Construct a client with this list of View lines +# +client_view() { + ( + cat <<-EOF && + Client: client + Description: client + Root: $cli + View: + EOF + for arg ; do + printf "\t$arg\n" + done + ) | p4 client -i +} + diff --git a/t/t9809-git-p4-client-view.sh b/t/t9809-git-p4-client-view.sh index 7d993ef..281be29 100755 --- a/t/t9809-git-p4-client-view.sh +++ b/t/t9809-git-p4-client-view.sh @@ -9,23 +9,6 @@ test_expect_success 'start p4d' ' ' # -# Construct a client with this list of View lines -# -client_view() { - ( - cat <<-EOF && - Client: client - Description: client - Root: $cli - View: - EOF - for arg ; do - printf "\t$arg\n" - done - ) | p4 client -i -} - -# # Verify these files exist, exactly. Caller creates # a list of files in file "files". # -- 1.7.12.rc2.24.gc304662 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/5] git p4 test: add broken --use-client-spec --detect-branches tests
Signed-off-by: Pete Wyckoff --- t/t9801-git-p4-branch.sh | 77 1 file changed, 77 insertions(+) diff --git a/t/t9801-git-p4-branch.sh b/t/t9801-git-p4-branch.sh index 99fe16b..ca3a7f9 100755 --- a/t/t9801-git-p4-branch.sh +++ b/t/t9801-git-p4-branch.sh @@ -410,6 +410,83 @@ test_expect_failure 'git p4 clone file subset branch' ' test_path_is_missing file3 ) ' + +# From a report in http://stackoverflow.com/questions/11893688 +# where --use-client-spec caused branch prefixes not to be removed; +# every file in git appeared into a subdirectory of the branch name. +test_expect_success 'use-client-spec detect-branches setup' ' + rm -rf "$cli" && + mkdir "$cli" && + ( + cd "$cli" && + client_view "//depot/usecs/... //client/..." && + mkdir b1 && + echo b1/b1-file1 >b1/b1-file1 && + p4 add b1/b1-file1 && + p4 submit -d "b1/b1-file1" && + + p4 integrate //depot/usecs/b1/... //depot/usecs/b2/... && + p4 submit -d "b1 -> b2" && + p4 branch -i <<-EOF && + Branch: b2 + View: //depot/usecs/b1/... //depot/usecs/b2/... + EOF + + echo b2/b2-file2 >b2/b2-file2 && + p4 add b2/b2-file2 && + p4 submit -d "b2/b2-file2" + ) +' + +test_expect_failure 'use-client-spec detect-branches files in top-level' ' + test_when_finished cleanup_git && + test_create_repo "$git" && + ( + cd "$git" && + git p4 sync --detect-branches --use-client-spec //depot/usecs@all && + git checkout -b master p4/usecs/b1 && + test_path_is_file b1-file1 && + test_path_is_missing b2-file2 && + test_path_is_missing b1 && + test_path_is_missing b2 && + + git checkout -b b2 p4/usecs/b2 && + test_path_is_file b1-file1 && + test_path_is_file b2-file2 && + test_path_is_missing b1 && + test_path_is_missing b2 + ) +' + +test_expect_success 'use-client-spec detect-branches skips branches setup' ' + ( + cd "$cli" && + + p4 integrate //depot/usecs/b1/... //depot/usecs/b3/... && + p4 submit -d "b1 -> b3" && + p4 branch -i <<-EOF && + Branch: b3 + View: //depot/usecs/b1/... //depot/usecs/b3/... + EOF + + echo b3/b3-file3 >b3/b3-file3 && + p4 add b3/b3-file3 && + p4 submit -d "b3/b3-file3" + ) +' + +test_expect_success 'use-client-spec detect-branches skips branches' ' + client_view "//depot/usecs/... //client/..." \ + "-//depot/usecs/b3/... //client/b3/..." && + test_when_finished cleanup_git && + test_create_repo "$git" && + ( + cd "$git" && + git p4 sync --detect-branches --use-client-spec //depot/usecs@all && + test_must_fail git rev-parse refs/remotes/p4/usecs/b3 + ) +' + test_expect_success 'kill p4d' ' kill_p4d ' -- 1.7.12.rc2.24.gc304662 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/5] git p4: set self.branchPrefixes in initialization
This instance variable is needed during commit() to map files from p4 to their relative locations in git. Set it when initializing P4Sync to avoid passing it to every commit() call. Signed-off-by: Pete Wyckoff --- git-p4.py | 25 ++--- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/git-p4.py b/git-p4.py index e67d37d..6d07115 100755 --- a/git-p4.py +++ b/git-p4.py @@ -2041,10 +2041,9 @@ class P4Sync(Command, P4UserMap): gitStream.write(description) gitStream.write("\n") -def commit(self, details, files, branch, branchPrefixes, parent = ""): +def commit(self, details, files, branch, parent = ""): epoch = details["time"] author = details["user"] -self.branchPrefixes = branchPrefixes if self.verbose: print "commit into %s" % branch @@ -2053,7 +2052,7 @@ class P4Sync(Command, P4UserMap): # create a commit. new_files = [] for f in files: -if [p for p in branchPrefixes if p4PathStartsWith(f['path'], p)]: +if [p for p in self.branchPrefixes if p4PathStartsWith(f['path'], p)]: new_files.append (f) else: sys.stderr.write("Ignoring file outside of prefix: %s\n" % f['path']) @@ -2070,8 +2069,8 @@ class P4Sync(Command, P4UserMap): self.gitStream.write("data < 0: self.gitStream.write(": options = %s" % details['options']) self.gitStream.write("]\nEOT\n\n") @@ -2094,7 +2093,7 @@ class P4Sync(Command, P4UserMap): print "Change %s is labelled %s" % (change, labelDetails) files = p4CmdList(["files"] + ["%s...@%s" % (p, change) -for p in branchPrefixes]) +for p in self.branchPrefixes]) if len(files) == len(labelRevisions): @@ -2405,6 +2404,7 @@ class P4Sync(Command, P4UserMap): for branch in branches.keys(): ## HACK --hwn branchPrefix = self.depotPaths[0] + branch + "/" +self.branchPrefixes = [ branchPrefix ] parent = "" @@ -2449,19 +2449,19 @@ class P4Sync(Command, P4UserMap): tempBranch = os.path.join(self.tempBranchLocation, "%d" % (change)) if self.verbose: print "Creating temporary branch: " + tempBranch -self.commit(description, filesForCommit, tempBranch, [branchPrefix]) +self.commit(description, filesForCommit, tempBranch) self.tempBranches.append(tempBranch) self.checkpoint() blob = self.searchParent(parent, branch, tempBranch) if blob: -self.commit(description, filesForCommit, branch, [branchPrefix], blob) +self.commit(description, filesForCommit, branch, blob) else: if self.verbose: print "Parent of %s not found. Committing into head of %s" % (branch, parent) -self.commit(description, filesForCommit, branch, [branchPrefix], parent) +self.commit(description, filesForCommit, branch, parent) else: files = self.extractFilesFromCommit(description) -self.commit(description, files, self.branch, self.depotPaths, +self.commit(description, files, self.branch, self.initialParent) self.initialParent = "" except IOError: @@ -2525,7 +2525,7 @@ class P4Sync(Command, P4UserMap): self.updateOptionDict(details) try: -self.commit(details, self.extractFilesFromCommit(details), self.branch, self.depotPaths) +self.commit(details, self.extractFilesFromCommit(details), self.branch) except IOError: print "IO error with git fast-import. Is your git version recent enough?" print self.gitError.read() @@ -2683,6 +2683,9 @@ class P4Sync(Command, P4UserMap): self.depotPaths = newPaths +# --detect-branches may change this for each branch +self.branchPrefixes = self.depotPaths + self.loadUserMapFromCache() self.labels = {} if self.detectLabels: -- 1.7.12.rc2.24.gc304662 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/5] git p4: do wildcard decoding in stripRepoPath
Instead of having to remember to do it after each call to stripRepoPath, make it part of that function. Signed-off-by: Pete Wyckoff --- git-p4.py | 17 - 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/git-p4.py b/git-p4.py index 6d07115..e20ff5d 100755 --- a/git-p4.py +++ b/git-p4.py @@ -1819,15 +1819,17 @@ class P4Sync(Command, P4UserMap): def stripRepoPath(self, path, prefixes): if self.useClientSpec: -return self.clientSpecDirs.map_in_client(path) +path = self.clientSpecDirs.map_in_client(path) -if self.keepRepoPath: -prefixes = [re.sub("^(//[^/]+/).*", r'\1', prefixes[0])] +else: +if self.keepRepoPath: +prefixes = [re.sub("^(//[^/]+/).*", r'\1', prefixes[0])] -for p in prefixes: -if p4PathStartsWith(path, p): -path = path[len(p):] +for p in prefixes: +if p4PathStartsWith(path, p): +path = path[len(p):] +path = wildcard_decode(path) return path def splitFilesIntoBranches(self, commit): @@ -1849,7 +1851,6 @@ class P4Sync(Command, P4UserMap): fnum = fnum + 1 relPath = self.stripRepoPath(path, self.depotPaths) -relPath = wildcard_decode(relPath) for branch in self.knownBranches.keys(): @@ -1867,7 +1868,6 @@ class P4Sync(Command, P4UserMap): def streamOneP4File(self, file, contents): relPath = self.stripRepoPath(file['depotFile'], self.branchPrefixes) -relPath = wildcard_decode(relPath) if verbose: sys.stderr.write("%s\n" % relPath) @@ -1936,7 +1936,6 @@ class P4Sync(Command, P4UserMap): def streamOneP4Deletion(self, file): relPath = self.stripRepoPath(file['path'], self.branchPrefixes) -relPath = wildcard_decode(relPath) if verbose: sys.stderr.write("delete %s\n" % relPath) self.gitStream.write("D %s\n" % relPath) -- 1.7.12.rc2.24.gc304662 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 5/5] git p4: make branch detection work with --use-client-spec
The bug report in http://stackoverflow.com/questions/11893688 observes that files are mapped into the wrong locations in git when both --use-client-spec and --branch-detection are enabled. Fix this by changing the relative path prefix to match discovered branches when using a client spec. The problem was likely introduced with ecb7cf9 (git-p4: rewrite view handling, 2012-01-02). Signed-off-by: Pete Wyckoff --- git-p4.py| 37 +++-- t/t9801-git-p4-branch.sh | 2 +- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/git-p4.py b/git-p4.py index e20ff5d..aed1a2d 100755 --- a/git-p4.py +++ b/git-p4.py @@ -1818,21 +1818,41 @@ class P4Sync(Command, P4UserMap): return files def stripRepoPath(self, path, prefixes): +"""When streaming files, this is called to map a p4 depot path + to where it should go in git. The prefixes are either + self.depotPaths, or self.branchPrefixes in the case of + branch detection.""" + if self.useClientSpec: +# branch detection moves files up a level (the branch name) +# from what client spec interpretation gives path = self.clientSpecDirs.map_in_client(path) +if self.detectBranches: +for b in self.knownBranches: +if path.startswith(b + "/"): +path = path[len(b)+1:] + +elif self.keepRepoPath: +# Preserve everything in relative path name except leading +# //depot/; just look at first prefix as they all should +# be in the same depot. +depot = re.sub("^(//[^/]+/).*", r'\1', prefixes[0]) +if p4PathStartsWith(path, depot): +path = path[len(depot):] else: -if self.keepRepoPath: -prefixes = [re.sub("^(//[^/]+/).*", r'\1', prefixes[0])] - for p in prefixes: if p4PathStartsWith(path, p): path = path[len(p):] +break path = wildcard_decode(path) return path def splitFilesIntoBranches(self, commit): +"""Look at each depotFile in the commit to figure out to what + branch it belongs.""" + branches = {} fnum = 0 while commit.has_key("depotFile%s" % fnum): @@ -1850,11 +1870,16 @@ class P4Sync(Command, P4UserMap): file["type"] = commit["type%s" % fnum] fnum = fnum + 1 -relPath = self.stripRepoPath(path, self.depotPaths) +# start with the full relative path where this file would +# go in a p4 client +if self.useClientSpec: +relPath = self.clientSpecDirs.map_in_client(path) +else: +relPath = self.stripRepoPath(path, self.depotPaths) for branch in self.knownBranches.keys(): - -# add a trailing slash so that a commit into qt/4.2foo doesn't end up in qt/4.2 +# add a trailing slash so that a commit into qt/4.2foo +# doesn't end up in qt/4.2, e.g. if relPath.startswith(branch + "/"): if branch not in branches: branches[branch] = [] diff --git a/t/t9801-git-p4-branch.sh b/t/t9801-git-p4-branch.sh index ca3a7f9..c5f0977 100755 --- a/t/t9801-git-p4-branch.sh +++ b/t/t9801-git-p4-branch.sh @@ -438,7 +438,7 @@ test_expect_success 'use-client-spec detect-branches setup' ' ) ' -test_expect_failure 'use-client-spec detect-branches files in top-level' ' +test_expect_success 'use-client-spec detect-branches files in top-level' ' test_when_finished cleanup_git && test_create_repo "$git" && ( -- 1.7.12.rc2.24.gc304662 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 2/2] git-svn.perl: keep processing all commits in parents_exclude
This fixes a bug where git finds the incorrect merge parent. Consider a repository with trunk, branch1 of trunk, and branch2 of branch1. Without this change, git interprets a merge of branch2 into trunk as a merge of branch1 into trunk. Signed-off-by: Steven Walter --- git-svn.perl |1 - t/t9164-git-svn-fetch-merge-branch-of-branch2.sh | 53 ++ 2 files changed, 53 insertions(+), 1 deletion(-) create mode 100755 t/t9164-git-svn-fetch-merge-branch-of-branch2.sh diff --git a/git-svn.perl b/git-svn.perl index abcec11..c4678c1 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -3623,7 +3623,6 @@ sub parents_exclude { if ( $commit eq $excluded ) { push @excluded, $commit; $found++; - last; } else { push @new, $commit; diff --git a/t/t9164-git-svn-fetch-merge-branch-of-branch2.sh b/t/t9164-git-svn-fetch-merge-branch-of-branch2.sh new file mode 100755 index 000..af0ec0e --- /dev/null +++ b/t/t9164-git-svn-fetch-merge-branch-of-branch2.sh @@ -0,0 +1,53 @@ +#!/bin/sh +# +# Copyright (c) 2012 Steven Walter +# + +test_description='git svn merge detection' +. ./lib-git-svn.sh + +svn_ver="$(svn --version --quiet)" +case $svn_ver in +0.* | 1.[0-4].*) + skip_all="skipping git-svn test - SVN too old ($svn_ver)" + test_done + ;; +esac + +test_expect_success 'initialize source svn repo' ' + svn_cmd mkdir -m x "$svnrepo"/trunk && + svn_cmd mkdir -m x "$svnrepo"/branches && + svn_cmd co "$svnrepo"/trunk "$SVN_TREE" && + ( + cd "$SVN_TREE" && + touch foo && + svn_cmd add foo && + svn_cmd commit -m "initial commit" && + svn_cmd cp -m branch "$svnrepo"/trunk "$svnrepo"/branches/branch1 && + svn_cmd switch "$svnrepo"/branches/branch1 && + touch bar && + svn_cmd add bar && + svn_cmd commit -m branch1 && + svn_cmd cp -m branch "$svnrepo"/branches/branch1 "$svnrepo"/branches/branch2 && + svn_cmd switch "$svnrepo"/branches/branch2 && + touch baz && + svn_cmd add baz && + svn_cmd commit -m branch2 && + svn_cmd switch "$svnrepo"/trunk && + svn_cmd merge --reintegrate "$svnrepo"/branches/branch2 && + svn_cmd commit -m "merge branch2" + ) && + rm -rf "$SVN_TREE" +' + +test_expect_success 'clone svn repo' ' + git svn init -s "$svnrepo" && + git svn fetch +' + +test_expect_success 'verify merge commit' 'x=$(git rev-parse HEAD^2) && + y=$(git rev-parse branch2) && + test "x$x" = "x$y" +' + +test_done -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 1/2] git-svn.perl: consider all ranges for a given merge, instead of only tip-by-tip
Consider the case where you have trunk, branchA of trunk, and branchB of branchA. trunk is merged back into branchB, and then branchB is reintegrated into trunk. The merge of branchB into trunk will have svn:mergeinfo property references to both branchA and branchB. When performing the check_cherry_pick check on branchB, it is necessary to eliminate the merged contents of branchA as well as branchB, or else the merge will be incorrectly ignored as a cherry-pick. Signed-off-by: Steven Walter --- git-svn.perl|8 ++- t/t9163-git-svn-fetch-merge-branch-of-branch.sh | 60 +++ 2 files changed, 63 insertions(+), 5 deletions(-) create mode 100755 t/t9163-git-svn-fetch-merge-branch-of-branch.sh diff --git a/git-svn.perl b/git-svn.perl index ca038ec..abcec11 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -3657,14 +3657,14 @@ sub find_extra_svn_parents { my @merge_tips; my $url = $self->{url}; my $uuid = $self->ra_uuid; - my %ranges; + my @all_ranges; for my $merge ( @merges ) { my ($tip_commit, @ranges) = lookup_svn_merge( $uuid, $url, $merge ); unless (!$tip_commit or grep { $_ eq $tip_commit } @$parents ) { push @merge_tips, $tip_commit; - $ranges{$tip_commit} = \@ranges; + push @all_ranges, @ranges; } else { push @merge_tips, undef; } @@ -3679,8 +3679,6 @@ sub find_extra_svn_parents { my $spec = shift @merges; next unless $merge_tip and $excluded{$merge_tip}; - my $ranges = $ranges{$merge_tip}; - # check out 'new' tips my $merge_base; eval { @@ -3702,7 +3700,7 @@ sub find_extra_svn_parents { my (@incomplete) = check_cherry_pick( $merge_base, $merge_tip, $parents, - @$ranges, + @all_ranges, ); if ( @incomplete ) { diff --git a/t/t9163-git-svn-fetch-merge-branch-of-branch.sh b/t/t9163-git-svn-fetch-merge-branch-of-branch.sh new file mode 100755 index 000..13ae7e3 --- /dev/null +++ b/t/t9163-git-svn-fetch-merge-branch-of-branch.sh @@ -0,0 +1,60 @@ +#!/bin/sh +# +# Copyright (c) 2012 Steven Walter +# + +test_description='git svn merge detection' +. ./lib-git-svn.sh + +svn_ver="$(svn --version --quiet)" +case $svn_ver in +0.* | 1.[0-4].*) + skip_all="skipping git-svn test - SVN too old ($svn_ver)" + test_done + ;; +esac + +test_expect_success 'initialize source svn repo' ' + svn_cmd mkdir -m x "$svnrepo"/trunk && + svn_cmd mkdir -m x "$svnrepo"/branches && + svn_cmd co "$svnrepo"/trunk "$SVN_TREE" && + ( + cd "$SVN_TREE" && + touch foo && + svn_cmd add foo && + svn_cmd commit -m "initial commit" && + svn_cmd cp -m branch "$svnrepo"/trunk "$svnrepo"/branches/branch1 && + svn_cmd switch "$svnrepo"/branches/branch1 && + touch bar && + svn_cmd add bar && + svn_cmd commit -m branch1 && + svn_cmd cp -m branch "$svnrepo"/branches/branch1 "$svnrepo"/branches/branch2 && + svn_cmd switch "$svnrepo"/branches/branch2 && + touch baz && + svn_cmd add baz && + svn_cmd commit -m branch2 && + svn_cmd switch "$svnrepo"/trunk && + touch bar2 && + svn_cmd add bar2 && + svn_cmd commit -m trunk && + svn_cmd switch "$svnrepo"/branches/branch2 && + svn_cmd merge "$svnrepo"/trunk && + svn_cmd commit -m "merge trunk" + svn_cmd switch "$svnrepo"/trunk && + svn_cmd merge --reintegrate "$svnrepo"/branches/branch2 && + svn_cmd commit -m "merge branch2" + ) && + rm -rf "$SVN_TREE" +' + +test_expect_success 'clone svn repo' ' + git svn init -s "$svnrepo" && + git svn fetch +' + +test_expect_success 'verify merge commit' 'x=$(git rev-parse HEAD^2) && + y=$(git rev-parse branch2) && + test "x$x" = "x$y" +' + +test_done -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: git archive --format zip utf-8 issues
Am 11.08.2012 00:47, schrieb Junio C Hamano: Sven Strickroth writes: when I create a git repository, add a file containing utf-8 characters or umlauts (like öäü.txt), commit and then export the HEAD revision to a zip archive using "git archive --format zip -o 1.zip HEAD", the zip file contains incorrect filenames: My reading of archive-zip.c seems to suggest that we write out whatever pathname you have in the tree, so a pathname encoded in UTF-8 will be literally written out in the resulting zip archive. Sorry for my imperialistic attitude of "ASCII filenames should be enough for everybody". Laziness.. Do you know in what encoding the pathnames are _expected_ to be stored in zip archives? Random documentation seems to suggest that there is no standard encoding, e.g. http://docs.python.org/library/zipfile.html says: There is no official file name encoding for ZIP files. If you have unicode file names, you must convert them to byte strings in your desired encoding before passing them to write(). WinZip interprets all file names as encoded in CP437, also known as DOS Latin. which may explain it. http://www.pkware.com/documents/casestudies/APPNOTE.TXT is the standard document, as Sven noted, and it says that filenames are encoded in code page 437, or optionally UTF-8 (a later addition). Discussions like http://stackoverflow.com/questions/106367/ seem to indicate that at least some archivers use the local code page as well. It may not be a bad idea for "git archive --format=zip" to (1) check if pathname is a correct UTF-8; and (2) check if it can be reencoded to latin-1 and if (and only if) both are true, automatically re-encode the path to latin-1. The standard says we need to convert to CP437, or to UTF-8, or provide both versions. A more interesting question is: What's supported by which programs? The ZIP functionality built into Windows 7 doesn't seem to work with UTF-8 encoded filenames (except for those that only use the ASCII subset), and to ignore the UTF-8 part if both are given. Handling umlauts should be possible anyway, because they are on code page 437, but for other characters we'd have to aim for compatibility with other programs like Info-ZIP and 7-Zip. How do we know which encoding was used for a filename? Of course, "git archive --format=zip --path-reencode=utf8-to-latin1" would be the most generic way to do this. I really hope we can make do without additional options. René -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: git archive --format zip utf-8 issues
Am 11.08.2012 01:53, schrieb Sven Strickroth: Am 11.08.2012 00:47 schrieb Junio C Hamano: Do you know in what encoding the pathnames are _expected_ to be stored in zip archives? re-encoding to latin1 does not always work and may break double byte totally (e.g. chinese or japanese). PKZIP APPNOTE seems to be the zip standard and it specifies a utf-8 flag: http://www.pkware.com/documents/casestudies/APPNOTE.TXT A. Local file header: general purpose bit flag: (2 bytes) Bit 11: Language encoding flag (EFS). If this bit is set, the filename and comment fields for this file must be encoded using UTF-8. (see APPENDIX D) Yes, that's one of the two methods for supporting UTF-8 filenames described there. The other method involves writing extra ZIP header fields and was invented by Info-ZIP. They don't use it consistently anymore, though (from zip -h2): "Zip now stores UTF-8 in entry path and comment fields on systems where UTF-8 char set is default, such as most modern Unix, and and on other systems in new extra fields with escaped versions in entry path and comment fields for backward compatibility." René -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: git archive --format zip utf-8 issues
Am 11.08.2012 22:53 schrieb René Scharfe: > The standard says we need to convert to CP437, or to UTF-8, or provide > both versions. A more interesting question is: What's supported by which > programs? > > The ZIP functionality built into Windows 7 doesn't seem to work with > UTF-8 encoded filenames (except for those that only use the ASCII > subset), and to ignore the UTF-8 part if both are given. I played a bit with the git source code and found out, that diff --git a/archive-zip.c b/archive-zip.c index f5af81f..e0ccb4f 100644 --- a/archive-zip.c +++ b/archive-zip.c @@ -257,7 +257,7 @@ static int write_zip_entry(struct archiver_args *args, copy_le16(dirent.creator_version, S_ISLNK(mode) || (S_ISREG(mode) && (mode & 0111)) ? 0x0317 : 0); copy_le16(dirent.version, 10); - copy_le16(dirent.flags, flags); + copy_le16(dirent.flags, flags+2048); copy_le16(dirent.compression_method, method); copy_le16(dirent.mtime, zip_time); copy_le16(dirent.mdate, zip_date); -- works with 7-zip, however, not with Windows 7 build-in zip. If I create a zip file with 7-zip which contains umlauts and other unicode chars like (國立1-.txt) the Windows 7 build-in zip displays them correctly, too. -- Best regards, Sven Strickroth PGP key id F5A9D4C4 @ any key-server -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: git archive --format zip utf-8 issues
René Scharfe writes: >> PKZIP APPNOTE seems to be the zip standard and it specifies a utf-8 >> flag: http://www.pkware.com/documents/casestudies/APPNOTE.TXT >>> A. Local file header: >>> general purpose bit flag: (2 bytes) >>> Bit 11: Language encoding flag (EFS). If this bit is >>> set, the filename and comment fields for this file >>> must be encoded using UTF-8. (see APPENDIX D) > > Yes, that's one of the two methods for supporting UTF-8 filenames > described there. > > The other method involves writing extra ZIP header fields and was > invented by Info-ZIP. They don't use it consistently anymore, though > (from zip -h2): > > "Zip now stores UTF-8 in entry path and comment fields on systems > where UTF-8 char set is default, such as most modern Unix, and > and on other systems in new extra fields with escaped versions in > entry path and comment fields for backward compatibility." Thanks; so if we adopt one of these methods, the readers that matter will be happy? And if so, which one? Or both? -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: git archive --format zip utf-8 issues
René Scharfe writes: > ... A more interesting question is: What's supported by > which programs? Yes, that is the most interesting question. >> Of course, "git archive --format=zip --path-reencode=utf8-to-latin1" >> would be the most generic way to do this. > > I really hope we can make do without additional options. We need to at least know the path encoding used in the tree objects, and I'd be OK with a solution that assumes a single encoding is used for the entire tree. We would eventually need to also know the encoding used on the local working tree (i.e. in what encoding paths are returned from readdir() and the pathspec the user gives us from the command line), and iconv it to the tree objects encoding for the project when creating a cache_entry object to be fed to add_to_index(), and iconv it back from the tree objects encoding to the working tree encoding in write_entry(), but that is a longer term direction. For now, in order to address the immediate issue, we only need the tree object encoding, which should default to UTF-8 for interoperability. So "git archive --format=zip --in-object-path-encoding=big5" for a project whose tree object pathnames are in that encoding (and we always record paths in UTF-8 when writing zipfiles) should be the minimal that we need for now. Optionally, with a configuration variable i18n.inObjectPathEncoding (as opposed to the eventual i18n.worktreePathEncoding) set to big5, users of such a project can say "git archive --format=zip" without the "--in-object-path-encoding" option. Considering that zip is a format meant for exchange, I'd think we would be fine to always write in UTF-8 and leaving the readers responsible for converting the pathname while extracting. If a major zip extractor is incapable of handling UTF-8 (or even if capable it is cumbersome, for that matter), we may end up having to add "--in-archive-path-encoding=UTF-8" option to "git archive", with associated "zip.archivePathEncoding" variable, though. -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] help: correct behavior for is_executable on Windows
Heiko Voigt writes: > help.c | 15 --- > 1 file changed, 12 insertions(+), 3 deletions(-) > > diff --git a/help.c b/help.c > index 662349d..b41fa21 100644 > --- a/help.c > +++ b/help.c > @@ -103,10 +103,19 @@ static int is_executable(const char *name) > return 0; > > #if defined(WIN32) || defined(__CYGWIN__) > + /* On Windows we cannot use the executable bit. The executable > + * state is determined by extension only. We do this first > + * because with virus scanners opening an executeable for > + * reading is potentially expensive. > + */ > + if (has_extension(name, ".exe")) > + return S_IXUSR; > + > #if defined(__CYGWIN__) > if ((st.st_mode & S_IXUSR) == 0) > #endif > -{/* cannot trust the executable bit, peek into the file instead */ > +{/* now that we know it does not have an executable extension, > +peek into the file instead */ > char buf[3] = { 0 }; > int n; > int fd = open(name, O_RDONLY); > @@ -114,8 +123,8 @@ if ((st.st_mode & S_IXUSR) == 0) > if (fd >= 0) { > n = read(fd, buf, 2); > if (n == 2) > - /* DOS executables start with "MZ" */ > - if (!strcmp(buf, "#!") || !strcmp(buf, "MZ")) > + /* look for a she-bang */ > + if (!strcmp(buf, "#!")) > st.st_mode |= S_IXUSR; > close(fd); > } Would it make sense to move this to compat/win32/, compat/cygwin.c, and compat/posix.c, each exporting is_executable(const char *path), so that we do not have to suffer the #ifdef mess? -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] i18n: mark progress strings for translation
Nguyễn Thái Ngọc Duy writes: > Signed-off-by: Nguyễn Thái Ngọc Duy > --- > I know it's late in the cycle so let's queue it for the next one > before I forget it. I won't necessarily be queuing this. Not forgetting is a responsibility of individual developers. But it is a good idea to show an early iteration for input from others. I personally do not think this makes much sense, as half the progress message you see comes from the other end of the connection, which does not know nor care what language you speak. -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 0/5] git p4: fix branch detection with --use-client-spec
Pete Wyckoff writes: > matt...@korich.net wrote on Fri, 10 Aug 2012 12:14 -0700: >> Using git p4 on git version 1.7.12.rc2 has path issues. Standard >> clone/sync ops apparently place detected master and branches on >> independent and parallel directory structures instead of git branches. >> See http://stackoverflow.com/q/11893688/1588831 for a full demo of the >> problem. > > Thank you for the detailed report. It is a bug in 1.7.12-rc2. Do you mean "a feature that was present in 1.7.11 without this bug was broken when used with 1.7.12-rc2"? Or do you mean "this bug exists in 1.7.12-rc2 (older versions may or may not have it, but I am stressing that it is not fixed)"? The description for [PATCH 5/5] blames v1.7.9-rc0~4^2~1, which tells me it is the latter. And if that were the case, and if this were in the area of the system I oversee, I wouldn't push it to the upcoming release at this late in the cycle, when I do not know what other things it might break while fixing this bug (in other words, a fix to an old bug is not an execuse to introduce a regression). But git-p4 is not in my area, so if you meant this should go in the upcoming 1.7.12 release, I'll queue them directly on 'master'. Please tell me what your preference is. Thanks. > This series fixes it, on top of origin/master. > > The crux of the matter is that files are mapped into the wrong > locations in git when both --use-client-spec and --branch-detection > are enabled. > > Pete Wyckoff (5): > git p4 test: move client_view() function to library > git p4 test: add broken --use-client-spec --detect-branches tests > git p4: set self.branchPrefixes in initialization > git p4: do wildcard decoding in stripRepoPath > git p4: make branch detection work with --use-client-spec > > git-p4.py | 75 +++-- > t/lib-git-p4.sh | 18 ++ > t/t9801-git-p4-branch.sh | 77 > +++ > t/t9809-git-p4-client-view.sh | 17 -- > 4 files changed, 146 insertions(+), 41 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2] Let submodule command exit with error status if path does not exist
Heiko Voigt writes: > I did not know that you prefer a space after the function name. I simply > imitated the style from C and there we do not have spaces. It makes the > style rules a bit more complicated. Wouldn't it be nicer to have the > same as in C so we have less rules? I do not think so, as they are different languages. The call site of C functions have name and opening parenthesis without a SP in between. The call site of shell functions do not even have parentheses. In any case, personal preferences (including mine) do not matter much, as there is no "this is scientificly superiour" in styles. > diff --git a/git-submodule.sh b/git-submodule.sh > index aac575e..48014f2 100755 > --- a/git-submodule.sh > +++ b/git-submodule.sh > @@ -109,7 +109,8 @@ resolve_relative_url () > # > module_list() > { > - git ls-files --error-unmatch --stage -- "$@" | > + (git ls-files --error-unmatch --stage -- "$@" || > + echo '16 0 ') | Is there a reason why the sentinel has to have the same mode pattern as a GITLINK entry, NULL SHA-1, stage #0? Or is the "path" being empty all that matters? Ah, OK, you did not want to touch the perl script downstream. I would have preferred a comment to document that, i.e. ( git ls-files --error-unmatch --stage -- "$@" || # an entry with an empty $path used as a signal echo '16 0 0 ' ) | perl -e '... or ( git ls-files --error-unmatch --stage -- "$@" || echo 'unmatched pathspec exists' ) | perl -e ' ... while () { if (/^unmatched pathspec/) { print; next; } chomp; my ($mode, $sha1, $stage, $path) = ... Either way, the reader of the code would not have to scratch her head that way. > perl -e ' > my %unmerged = (); > my ($null_sha1) = ("0" x 40); > @@ -385,6 +386,10 @@ cmd_foreach() > module_list | > while read mode sha1 stage sm_path > do > + if test -z "$sm_path"; then > + exit 1 Style: if test -z "$sm_path" then exit 1 I know module_list would have said "error: pathspec 'no-such' did not match any file(s) known to git. Did you forget to git add" already, but because that comes at the very end of the input to the filter written in perl (and with the way the filter is coded, it will stay at the end), I am not sure if the user would notice it if we exit like this. By the time we hit this exit, we would have seen "Entering $sm_path..." followed by whatever message given while in the submodule for all the submodules that comes out of module_list, no? How about doing it this way to avoid that issue, to make sure we die immediately after the typo is diagnosed without touching anything? git-submodule.sh | 32 +--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/git-submodule.sh b/git-submodule.sh index 3aa7644..3f99d71 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -109,26 +109,47 @@ resolve_relative_url () # module_list() { - git ls-files --error-unmatch --stage -- "$@" | + ( + git ls-files --error-unmatch --stage -- "$@" || + echo "unmatched pathspec exists" + ) | perl -e ' my %unmerged = (); my ($null_sha1) = ("0" x 40); + my @out = (); + my $unmatched = 0; while () { + if (/^unmatched pathspec/) { + $unmatched = 1; + next; + } chomp; my ($mode, $sha1, $stage, $path) = /^([0-7]+) ([0-9a-f]{40}) ([0-3])\t(.*)$/; next unless $mode eq "16"; if ($stage ne "0") { if (!$unmerged{$path}++) { - print "$mode $null_sha1 U\t$path\n"; + push @out, "$mode $null_sha1 U\t$path\n"; } next; } - print "$_\n"; + push @out, "$_\n"; + } + if ($unmatched) { + unshift @out, "#unmatched\n"; } + print for (@out); ' } +check_unmatched () +{ + if test "$1" = "#unmatched" + then + exit 1 + fi +} + # # Map submodule path to submodule name # @@ -385,6 +406,7 @@ cmd_foreach() module_list | while read mode sha1 stage sm_path do + check_unmatched "$mode" if test -e "$sm_path"/.git then say "$(eval_gettext "Entering '\$prefix\$sm_path'")" @@ -437,6 +459,7 @@ cmd_init() module_list "$@" | while read mode sha1