* Re: [PATCH v2 4/4] upload-archive: use start_command instead of fork
From: Jeff King @ 2011-08-09 20:05 UTC (permalink / raw)
To: René Scharfe; +Cc: Johannes Sixt, Erik Faye-Lund, Junio C Hamano, git
In-Reply-To: <4E410B26.1080407@lsrfire.ath.cx>
On Tue, Aug 09, 2011 at 12:25:42PM +0200, René Scharfe wrote:
> > BTW, as nice as this "gzip -cn | cat" idea is, I think it needs to be
> > wrapped in a shell script. With the code above, we will generate "gzip
> > -cn | cat -9".
>
> Yes, the three added lines in the patch above would have to be moved
> down two lines, after the compression level is added. D'oh!
Also, is adding "| cat" also sufficient for arbitrary shell code (i.e.,
whatever the user hands us via the config)? I couldn't think of an
example that wouldn't work.
> OK, that's one way to do it; another would be let gzip (and bzip2 etc.)
> do whatever cat does to avoid end of line conversions. And yet another
> is to take them from http://unxutils.sourceforge.net/.
Yeah, I like all of those solutions better than hacking an extra pipe
into git. I don't know enough to say how painful they are in practice,
though.
> > BTW, from what Johannes said, the issue is about a non-msys program
> > calling an msys one. Does that mean that having git run:
> >
> > sh -c 'gzip -cn'
> >
> > would work? If so, then could the solution be as simple as turning off
> > the "don't bother with the shell" optimization that run-command uses?
> > Something like "gzip -cn" gets split by git and run via spawn now
> > (because it has no metacharacters). But we could easily make it always
> > run through the shell.
>
> Just checked -- it doesn't work. I assume that's because the shell is
> also an MSYS program.
Too bad. I guess the first msys program to be run sets the mode of the
output descriptor, and then everybody else inherits that. If there were
a helper or shell builtin to switch to binary mode, we could put it at
the start of the shell pipeline.
If you write a C program that does:
setmode(1, O_BINARY);
and call it like:
./setmode-helper; gzip -cn
does that work? I suspect not, as from my brief reading of the msys gzip
source, it actually calls setmode() itself.
-Peff
^ permalink raw reply
* Tracked files become untracked in some obscure scenario
From: Stéphane Corlosquet @ 2011-08-09 19:59 UTC (permalink / raw)
To: git
Hi,
I'm encountering a very strange bug where some directory containing
one file becomes untracked when it should be tracked. I originally
found this bug in a bigger repository, but I isolated the culprit
files into a small tarball which you can download from
http://files.openspring.net/tmp/gitbug-20110809.tgz
This bug occurs on the following three configs:
Mac OS X Snow Leopard with git 1.7.4.1
Mac OS X Snow Leopard with git 1.7.5
Mac OS X Lion with git 1.7.4.4
I could not reproduce on Ubuntu.
To reproduce, extract the tarball and try to add its content into a fresh repo:
$ git init
Initialized empty Git repository in /private/tmp/stemtest/.git/
$ git add .
$ git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
# (use "git rm --cached <file>..." to unstage)
#
# new file: drupal/sites/all/modules/scf/pubnode_docbook4/xsl/docbook-xsl-1.73.2/common/olink.xsl
# new file: files/pubnode/ab4d8c648ef8e26312beaba802a503d1f8081bb6/README
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# files/pubnode/ab4d8c648ef8e26312beaba802a503d1f8081bb6/
From there onwards, if I commit and do other operations, this
directory will remain in the untracked files list. I'm terribly
confused by this bug. It seems it has to do with the paths of both
files, since if I rename them, the bug does not happen. But I can't
explain what's going on.
regards,
Steph.
^ permalink raw reply
* Re: [PATCH 2/2] On Cygwin support both UNIX and DOS style path-names
From: Johannes Sixt @ 2011-08-09 19:47 UTC (permalink / raw)
To: Pascal Obry; +Cc: git
In-Reply-To: <1312560614-20772-3-git-send-email-pascal@obry.net>
Am 05.08.2011 18:10, schrieb Pascal Obry:
> In fact Cygwin supports both, so make Git agree with this.
> The failing case is when a file is committed in a sub-dir of the
> repository using a log message from a file specified with a DOS
> style path-name. To reproduce:
>
> $ cd src
> $ git commit -F c:\tmp\log.txt file.c
> fatal: could not read log file 'src/c:\tmp\log.txt': No such file \
> or directory.
Do you also want to support this:
$ git add src\file.c
i.e., backslash in pathspec? Then you need more than this:
> +#define has_dos_drive_prefix(path) (isalpha(*(path)) && (path)[1] == ':')
> +#define is_dir_sep(c) ((c) == '/' || (c) == '\\')
In particular, you have to enable backslash processing in
setup.c:prefix_filename(), but then you lose the ability to escape
special characters with the backslash.
-- Hannes
^ permalink raw reply
* Re: [PATCH] Support specific color for a specific remote branches
From: Aviv Eyal @ 2011-08-09 18:59 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano
In-Reply-To: <7v8vr3zsh1.fsf@alter.siamese.dyndns.org>
On 8 August 2011 21:08, Junio C Hamano <gitster@pobox.com> wrote:
>
> Who said a remote name is terminated with (and cannot contain) a slash?
...
>
> Shouldn't this code be consulting the configuration file to learn the
...
> so that remote branches from "frotz" remote, that happen to be stored
> under refs/remotes/nitfol/ hierarchy, are painted in the correct color?
>
Sorry, that's too dip & complex for me... Consider this patch 'withdrawn' then.
-- Aviv
^ permalink raw reply
* t5800-*.sh: Intermittent test failures
From: Ramsay Jones @ 2011-08-09 18:30 UTC (permalink / raw)
To: GIT Mailing-list; +Cc: srabbelier, Jeff King, Jonathan Nieder, Junio C Hamano
I've noticed some intermittent test failures in t5800-*.sh on Linux
recently. The failures (test #7 onwards) are due to a git-push to a
remote, via the git-remote-test helper, hanging in git-fast-import.
git-bisect fingers the following commit:
a515ebe9f1ac9bc248c12a291dc008570de505ca is the first bad commit
commit a515ebe9f1ac9bc248c12a291dc008570de505ca
Author: Sverre Rabbelier <srabbelier@gmail.com>
Date: Sat Jul 16 15:03:40 2011 +0200
transport-helper: implement marks location as capability
Now that the gitdir location is exported as an environment variable
this can be implemented elegantly without requiring any explicit
flushes nor an ad-hoc exchange of values.
Signed-off-by: Sverre Rabbelier <srabbelier@gmail.com>
Acked-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
:100644 100644 1ed7a5651ef5a2320c56856b5a1fe784e178ab23 e9c832bfd3da7db771cc2113
027d3e590dc51d59 M git-remote-testgit.py
:100644 100644 0cfc9ae9059ce121b567406d7941b71cd54b961c 74c3122df1835c45a6b62120
5fb18b4fc89af366 M transport-helper.c
which didn't seem too likely at first, but it does reduce the size of the
fast-import stream (by moving the import/export marks filenames to the
command line). This could change the timings enough to cause the problem.
I set various environment variables (eg GIT_TRANSLOOP_DEBUG, GIT_DEBUG_TESTGIT etc)
in order to get some additional clues, in addition to looking at the stackframe
of all of the processes in the hung pipeline, which looks like:
git(push)->git-remote-test->git(fast-import)->git-fast-import
The git-fast-import is hung in the read() syscall waiting for data which will
never arrive. This is because the git(fast-export) process, started by the above
git(push), executes (producing it's data on stdout) and completes successfully
and exits *before* the above git-fast-import process starts.
I haven't looked to see how the git(fast-export)/git-fast-import processes are
plumbed together, but there seems to be a synchronization problem somewhere ...
Unfortunately, I don't have time at the moment to finish debugging this, so I
was hoping someone who knows the code better than me could fix it up ...
Thanks! :-P
[I've included the stackframes (from the above pipeline) below in case it helps]
ATB,
Ramsay Jones
[git-fast-import]
(gdb) bt
#0 0xffffe410 in __kernel_vsyscall ()
#1 0xb7dd6033 in read () from /lib/tls/i686/cmov/libc.so.6
#2 0xb7d774f8 in _IO_file_read () from /lib/tls/i686/cmov/libc.so.6
#3 0xb7d788c0 in _IO_file_underflow () from /lib/tls/i686/cmov/libc.so.6
#4 0xb7d78fbb in _IO_default_uflow () from /lib/tls/i686/cmov/libc.so.6
#5 0xb7d7a31d in __uflow () from /lib/tls/i686/cmov/libc.so.6
#6 0xb7d742a0 in getc () from /lib/tls/i686/cmov/libc.so.6
#7 0x0807e203 in strbuf_getwholeline (sb=0x80e348c, fp=0xb7e53420, term=10)
at strbuf.c:361
#8 0x0807e262 in strbuf_getline (sb=0x80e348c, fp=0xb7e53420, term=10)
at strbuf.c:376
#9 0x0804f681 in read_next_command () at fast-import.c:1853
#10 0x0805368b in main (argc=4, argv=0xbf8eac74) at fast-import.c:3295
(gdb)
[git(fast-import)]
(gdb) bt
#0 0xffffe410 in __kernel_vsyscall ()
#1 0xb7dcf0b3 in __waitpid_nocancel () from /lib/tls/i686/cmov/libpthread.so.0
#2 0x08129706 in wait_or_whine (pid=6200, argv0=0x81e4070 "git-fast-import",
silent_exec_failure=1) at run-command.c:105
#3 0x0812a08f in finish_command (cmd=0xbfe42874) at run-command.c:415
#4 0x0812a0be in run_command (cmd=0xbfe42874) at run-command.c:423
#5 0x0812a1bf in run_command_v_opt (argv=0xbfe429dc, opt=8)
at run-command.c:443
#6 0x0804c12d in execv_dashed_external (argv=0xbfe429dc) at git.c:489
#7 0x0804c192 in run_argv (argcp=0xbfe42950, argv=0xbfe42954) at git.c:507
#8 0x0804c321 in main (argc=4, argv=0xbfe429dc) at git.c:577
(gdb)
[git-remote-test]
(gdb) bt
#0 0xffffe410 in __kernel_vsyscall ()
#1 0xb7f230b3 in __waitpid_nocancel () from /lib/tls/i686/cmov/libpthread.so.0
#2 0x080f8fc0 in posix_waitpid (self=0x0, args=0xb7d615ec)
at ../Modules/posixmodule.c:5636
... [snipped as uninteresting!]
(gdb)
[git(push)]
(gdb) bt
#0 0xffffe410 in __kernel_vsyscall ()
#1 0xb7dde033 in read () from /lib/tls/i686/cmov/libc.so.6
#2 0xb7d7f4f8 in _IO_file_read () from /lib/tls/i686/cmov/libc.so.6
#3 0xb7d808c0 in _IO_file_underflow () from /lib/tls/i686/cmov/libc.so.6
#4 0xb7d80fbb in _IO_default_uflow () from /lib/tls/i686/cmov/libc.so.6
#5 0xb7d8231d in __uflow () from /lib/tls/i686/cmov/libc.so.6
#6 0xb7d7c2a0 in getc () from /lib/tls/i686/cmov/libc.so.6
#7 0x08138d6b in strbuf_getwholeline (sb=0xbfb662c8, fp=0x81e4760, term=10)
at strbuf.c:361
#8 0x08138dca in strbuf_getline (sb=0xbfb662c8, fp=0x81e4760, term=10)
at strbuf.c:376
#9 0x0813ffe3 in recvline_fh (helper=0x81e4760, buffer=0xbfb662c8)
at transport-helper.c:51
#10 0x081400be in recvline (helper=0x81e44a0, buffer=0xbfb662c8)
at transport-helper.c:64
#11 0x08141a6e in push_update_refs_status (data=0x81e44a0,
remote_refs=0x81e48e8) at transport-helper.c:652
#12 0x08141e80 in push_refs_with_export (transport=0x81e4450,
remote_refs=0x81e48e8, flags=0) at transport-helper.c:759
#13 0x08141f74 in push_refs (transport=0x81e4450, remote_refs=0x81e48e8,
flags=0) at transport-helper.c:783
#14 0x0813f846 in transport_push (transport=0x81e4450, refspec_nr=1,
refspec=0x81e43e8, flags=0, nonfastforward=0xbfb6642c) at transport.c:1044
#15 0x080a3bda in push_with_options (transport=0x81e4450, flags=0)
at builtin/push.c:131
#16 0x080a3ea7 in do_push (repo=0x0, flags=0) at builtin/push.c:209
#17 0x080a4377 in cmd_push (argc=0, argv=0xbfb668c8, prefix=0x0)
at builtin/push.c:265
#18 0x0804bf3f in run_builtin (p=0x81977b4, argc=1, argv=0xbfb668c8)
at git.c:302
#19 0x0804c0a5 in handle_internal_command (argc=1, argv=0xbfb668c8)
at git.c:460
#20 0x0804c185 in run_argv (argcp=0xbfb66840, argv=0xbfb66844) at git.c:504
#21 0x0804c321 in main (argc=1, argv=0xbfb668c8) at git.c:577
(gdb)
^ permalink raw reply
* Re: [PATCH 2/2] On Cygwin support both UNIX and DOS style path-names
From: Ramsay Jones @ 2011-08-09 17:30 UTC (permalink / raw)
To: pascal; +Cc: kusmabite, git
In-Reply-To: <4E3C29D9.5060305@obry.net>
Pascal Obry wrote:
> Le 05/08/2011 19:29, Erik Faye-Lund a écrit :
>> Cygwin is a unix-layer on top of Windows, designed to play by the
>> POSIX-rules. So why would you want to support Windows-style paths on
>> Cygwin?
>
> Because cygwin toolset does support \.
Hmm, if you don't mind escaping it in bash all the time!
>
>> If you want a Git that handles Windows paths, use Git for Windows...
>
> Note that Windows is a special case as even the Win32 API does support \
> and /, so every tool on Windows seems to handle nicely this. Why not
> Git, be it Cygwin/Git. If it does not break anything else.
Hmm, I wouldn't be too sure of that, either ...
ATB,
Ramsay Jones
^ permalink raw reply
* Re: [PATCH 2/2] On Cygwin support both UNIX and DOS style path-names
From: Ramsay Jones @ 2011-08-09 17:26 UTC (permalink / raw)
To: kusmabite; +Cc: Pascal Obry, git
In-Reply-To: <CABPQNSYSzsY-CQdi6iJQftsY1ufMpxkax=eQLgopVxMC6LoxfA@mail.gmail.com>
Erik Faye-Lund wrote:
> On Fri, Aug 5, 2011 at 6:10 PM, Pascal Obry <pascal@obry.net> wrote:
>> In fact Cygwin supports both, so make Git agree with this.
>> The failing case is when a file is committed in a sub-dir of the
>> repository using a log message from a file specified with a DOS
>> style path-name. To reproduce:
>>
>> $ cd src
>> $ git commit -F c:\tmp\log.txt file.c
>> fatal: could not read log file 'src/c:\tmp\log.txt': No such file \
>> or directory.
>
> Cygwin is a unix-layer on top of Windows, designed to play by the
> POSIX-rules. So why would you want to support Windows-style paths on
> Cygwin?
>
> If you want a Git that handles Windows paths, use Git for Windows...
Indeed, I have to agree. This takes the cygwin port in the wrong
direction ...
ATB,
Ramsay Jones
^ permalink raw reply
* Re: [PATCH 2/2] On Cygwin support both UNIX and DOS style path-names
From: Ramsay Jones @ 2011-08-09 17:24 UTC (permalink / raw)
To: Pascal Obry; +Cc: git
In-Reply-To: <1312560614-20772-3-git-send-email-pascal@obry.net>
Pascal Obry wrote:
> In fact Cygwin supports both, so make Git agree with this.
> The failing case is when a file is committed in a sub-dir of the
> repository using a log message from a file specified with a DOS
> style path-name. To reproduce:
>
> $ cd src
> $ git commit -F c:\tmp\log.txt file.c
> fatal: could not read log file 'src/c:\tmp\log.txt': No such file \
> or directory.
Hmm, are you using bash or cmd.exe? Using bash I get the following:
$ cd src
$ git commut -F c:\tmp\log.txt file.c
fatal: could not read file 'src/c:tmplog.txt': No such file or directory
$
Which is what I would expect of (any) posix shell, viz:
$ ls c:\
> ^C
$ ls c:\\
AUTOEXEC.BAT* NTDETECT.COM* WATCOM/ msysgit/
CMPNENTS/ Program Files/ WINDOWS/ msysgit-old/
CONFIG.SYS* RECYCLER/ boot.ini* ntldr*
Documents and Settings/ SUPPORT/ cygwin/ pagefile.sys
I386/ SWSTAMP.TXT* cygwintemp/ ssl/
IO.SYS* System Volume Information/ dm/ uname/
MSDOS.SYS* TOOLSCD/ dm840/ zlib/
MSOCache/ VALUEADD/ hiberfil.sys
$
If you want to use cmd.exe as your shell, I suspect msysGit (Git For Windows)
may be a better fit.
ATB,
Ramsay Jones
^ permalink raw reply
* Re: [PATCH v2 2/2] Move git-dir for submodules
From: Heiko Voigt @ 2011-08-09 18:23 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Fredrik Gustafsson, git, jens.lehmann
In-Reply-To: <7v1uwvwpsk.fsf@alter.siamese.dyndns.org>
Hi,
On Mon, Aug 08, 2011 at 02:34:35PM -0700, Junio C Hamano wrote:
> Heiko Voigt <hvoigt@hvoigt.net> writes:
>
> > Hi,
> >
> > On Mon, Aug 08, 2011 at 09:17:02PM +0200, Fredrik Gustafsson wrote:
> >> diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh
> >> index c679f36..1ae6b4e 100755
> >> --- a/t/t7406-submodule-update.sh
> >> +++ b/t/t7406-submodule-update.sh
> >> @@ -408,6 +408,7 @@ test_expect_success 'submodule update exit immediately in case of merge conflict
> >> test_cmp expect actual
> >> )
> >> '
> >> +
> >
> > There is a whitespace error here which we seem to have overlooked. Junio
> > could you remove that?
>
> Hmm, confused.
>
> A blank between test would be the perfectly normal thing to see, no?
Yes indeed you are right I did just see the lonely new line here. I
missed that a blank line was missing previously here.
Cheers Heiko
^ permalink raw reply
* [PATCH] push: Don't push a repository with unpushed submodules
From: Fredrik Gustafsson @ 2011-08-09 18:15 UTC (permalink / raw)
To: git; +Cc: gitster, iveqy, hvoigt, jens.lehmann
When working with submodules it is easy to forget to push a
submodule to the server but pushing a super-project that
contains a commit for that submodule. The result is that the
superproject points at a submodule commit that is not available
on the server.
This adds the option --recurse-submodules=check to push. When
using this option git will check that all submodule commits that
are about to be pushed are present on a remote of the submodule.
This does not guarantee that all submodules a super-project
needs will be available on the server. In that case both the
super-project and the submodules would need an atomic push. This
does however prevent the human error of forgetting to push a
submodule.
Signed-off-by: Fredrik Gustafsson <iveqy@iveqy.com>
Mentored-by: Jens Lehmann <Jens.Lehmann@web.de>
Mentored-by: Heiko Voigt <hvoigt@hvoigt.net>
---
We decided to make this a one patch series since by the default
the check is turned off.
The first iteration of this patch series can be found here:
http://thread.gmane.org/gmane.comp.version-control.git/176328/focus=176327
A new test is added in this iteration to show a bug that now is fixed.
Documentation/git-push.txt | 6 ++
builtin/push.c | 17 +++++
submodule.c | 129 ++++++++++++++++++++++++++++++++++++++++
submodule.h | 1 +
t/t5531-deep-submodule-push.sh | 99 ++++++++++++++++++++++++++++++
transport.c | 9 +++
transport.h | 1 +
7 files changed, 262 insertions(+), 0 deletions(-)
diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt
index 88acfcd..6ae6ba3 100644
--- a/Documentation/git-push.txt
+++ b/Documentation/git-push.txt
@@ -162,6 +162,12 @@ useful if you write an alias or script around 'git push'.
is specified. This flag forces progress status even if the
standard error stream is not directed to a terminal.
+--recurse-submodules=check::
+ Check whether all submodule commits used by the revisions to be
+ pushed are available on a remote tracking branch. Otherwise the
+ push will be aborted and the command will exit with non-zero status.
+
+
include::urls-remotes.txt[]
OUTPUT
diff --git a/builtin/push.c b/builtin/push.c
index 9cebf9e..23ba365 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -8,6 +8,7 @@
#include "remote.h"
#include "transport.h"
#include "parse-options.h"
+#include "submodule.h"
static const char * const push_usage[] = {
"git push [<options>] [<repository> [<refspec>...]]",
@@ -219,6 +220,19 @@ static int do_push(const char *repo, int flags)
return !!errs;
}
+static int option_parse_recurse_submodules(const struct option *opt,
+ const char *arg, int unset)
+{
+ int *flags = opt->value;
+ if (arg) {
+ if (!strcmp(arg, "check"))
+ *flags |= TRANSPORT_RECURSE_SUBMODULES_CHECK;
+ else
+ die("bad %s argument: %s", opt->long_name, arg);
+ }
+ return 0;
+}
+
int cmd_push(int argc, const char **argv, const char *prefix)
{
int flags = 0;
@@ -236,6 +250,9 @@ int cmd_push(int argc, const char **argv, const char *prefix)
OPT_BIT('n' , "dry-run", &flags, "dry run", TRANSPORT_PUSH_DRY_RUN),
OPT_BIT( 0, "porcelain", &flags, "machine-readable output", TRANSPORT_PUSH_PORCELAIN),
OPT_BIT('f', "force", &flags, "force updates", TRANSPORT_PUSH_FORCE),
+ { OPTION_CALLBACK, 0, "recurse-submodules", &flags, "check",
+ "controls recursive pushing of submodules",
+ PARSE_OPT_OPTARG, option_parse_recurse_submodules },
OPT_BOOLEAN( 0 , "thin", &thin, "use thin pack"),
OPT_STRING( 0 , "receive-pack", &receivepack, "receive-pack", "receive pack program"),
OPT_STRING( 0 , "exec", &receivepack, "receive-pack", "receive pack program"),
diff --git a/submodule.c b/submodule.c
index 1ba9646..c44472f 100644
--- a/submodule.c
+++ b/submodule.c
@@ -308,6 +308,135 @@ void set_config_fetch_recurse_submodules(int value)
config_fetch_recurse_submodules = value;
}
+static int has_remote(const char *refname, const unsigned char *sha1, int flags, void *cb_data)
+{
+ return 1;
+}
+
+/*
+ * checks whether a certain submodule commit is pushed based on the
+ * submodules remote tracking branches. returns 1 in case no remote
+ * tracking branches are found.
+ */
+static int is_submodule_commit_pushed(const char *path, const unsigned char sha1[20])
+{
+ int is_pushed = 0;
+ if (!add_submodule_odb(path) && lookup_commit_reference(sha1)) {
+ if (for_each_remote_ref_submodule(path, has_remote, NULL)) {
+ struct child_process cp;
+ const char *argv[] = {"rev-list", NULL, "--not", "--remotes", "-n", "1" , NULL};
+ struct strbuf buf = STRBUF_INIT;
+
+ argv[1] = sha1_to_hex(sha1);
+ memset(&cp, 0, sizeof(cp));
+ cp.argv = argv;
+ cp.env = local_repo_env;
+ cp.git_cmd = 1;
+ cp.no_stdin = 1;
+ cp.out = -1;
+ cp.dir = path;
+ if (!run_command(&cp) && !strbuf_read(&buf, cp.out, 41))
+ is_pushed = 1;
+ close(cp.out);
+ strbuf_release(&buf);
+ } else
+ is_pushed = 1;
+ }
+ return is_pushed;
+}
+
+static void collect_unpushed_submodules_from_revs(struct diff_queue_struct *q,
+ struct diff_options *options,
+ void *data)
+{
+ int i;
+ int *found_unpushed_submodule = data;
+
+ for (i = 0; i < q->nr; i++) {
+ struct diff_filepair *p = q->queue[i];
+ if (!S_ISGITLINK(p->two->mode))
+ continue;
+ if (!is_submodule_commit_pushed(p->two->path, p->two->sha1)) {
+ *found_unpushed_submodule = 1;
+ break;
+ }
+ }
+}
+
+static int collect_unpushed_submodules_in_tree(const unsigned char *sha1,
+ const char *base, int baselen,
+ const char *pathname, unsigned mode,
+ int stage, void *context)
+{
+ int *found_unpushed_submodules = context;
+ struct strbuf path = STRBUF_INIT;
+
+ strbuf_add(&path, base, strlen(base));
+ strbuf_add(&path, pathname, strlen(pathname));
+
+ if (S_ISGITLINK(mode) && !is_submodule_commit_pushed(path.buf, sha1)) {
+ *found_unpushed_submodules = 1;
+ return 0;
+ }
+ return READ_TREE_RECURSIVE;
+}
+
+static void parent_commits_pushed(struct commit *commit, struct commit_list *parent, int *found_unpushed_submodule)
+{
+ while (parent) {
+ struct diff_options diff_opts;
+ diff_setup(&diff_opts);
+ DIFF_OPT_SET(&diff_opts, RECURSIVE);
+ diff_opts.output_format |= DIFF_FORMAT_CALLBACK;
+ diff_opts.format_callback = collect_unpushed_submodules_from_revs;
+ diff_opts.format_callback_data = found_unpushed_submodule;
+ if (diff_setup_done(&diff_opts) < 0)
+ die("diff_setup_done failed");
+ diff_tree_sha1(parent->item->object.sha1, commit->object.sha1, "", &diff_opts);
+ diffcore_std(&diff_opts);
+ diff_flush(&diff_opts);
+ parent = parent->next;
+ }
+}
+
+static void tree_commits_pushed(struct commit *commit, int *found_unpushed_submodule)
+{
+ struct tree * tree;
+ struct pathspec pathspec;
+ tree = parse_tree_indirect(commit->object.sha1);
+ init_pathspec(&pathspec,NULL);
+ read_tree_recursive(tree, "", 0, 0, &pathspec, collect_unpushed_submodules_in_tree,
+ found_unpushed_submodule);
+}
+
+int check_for_unpushed_submodule_commits(unsigned char new_sha1[20])
+{
+ struct rev_info rev;
+ struct commit *commit;
+ const char *argv[] = {NULL, NULL, "--not", "--remotes", NULL};
+ int argc = ARRAY_SIZE(argv) - 1;
+ char *sha1_copy;
+ int found_unpushed_submodule = 0;
+
+ init_revisions(&rev, NULL);
+ sha1_copy = xstrdup(sha1_to_hex(new_sha1));
+ argv[1] = sha1_copy;
+ setup_revisions(argc, argv, &rev, NULL);
+ if (prepare_revision_walk(&rev))
+ die("revision walk setup failed");
+
+ while ((commit = get_revision(&rev)) && !found_unpushed_submodule) {
+ struct commit_list *parent = commit->parents;
+ if (parent)
+ parent_commits_pushed(commit, parent, &found_unpushed_submodule);
+ else
+ tree_commits_pushed(commit, &found_unpushed_submodule);
+ }
+
+ free(sha1_copy);
+ return found_unpushed_submodule;
+}
+
static int is_submodule_commit_present(const char *path, unsigned char sha1[20])
{
int is_present = 0;
diff --git a/submodule.h b/submodule.h
index 5350b0d..0a4d395 100644
--- a/submodule.h
+++ b/submodule.h
@@ -29,5 +29,6 @@ int fetch_populated_submodules(int num_options, const char **options,
unsigned is_submodule_modified(const char *path, int ignore_untracked);
int merge_submodule(unsigned char result[20], const char *path, const unsigned char base[20],
const unsigned char a[20], const unsigned char b[20]);
+int check_for_unpushed_submodule_commits(unsigned char sha1[20]);
#endif
diff --git a/t/t5531-deep-submodule-push.sh b/t/t5531-deep-submodule-push.sh
index faa2e96..d3a1789 100755
--- a/t/t5531-deep-submodule-push.sh
+++ b/t/t5531-deep-submodule-push.sh
@@ -32,4 +32,103 @@ test_expect_success push '
)
'
+test_expect_success 'push if submodule has no remote' '
+ (
+ cd work/gar/bage &&
+ >junk2 &&
+ git add junk2 &&
+ git commit -m "Second junk"
+ ) &&
+ (
+ cd work &&
+ git add gar/bage &&
+ git commit -m "Second commit for gar/bage" &&
+ git push --recurse-submodules=check ../pub.git master
+ )
+'
+
+test_expect_success 'push fails if submodule commit not on remote' '
+ (
+ cd work/gar &&
+ git clone --bare bage ../../submodule.git &&
+ cd bage &&
+ git remote add origin ../../../submodule.git &&
+ git fetch &&
+ >junk3 &&
+ git add junk3 &&
+ git commit -m "Third junk"
+ ) &&
+ (
+ cd work &&
+ git add gar/bage &&
+ git commit -m "Third commit for gar/bage" &&
+ test_must_fail git push --recurse-submodules=check ../pub.git master
+ )
+'
+
+test_expect_success 'push succeeds after commit was pushed to remote' '
+ (
+ cd work/gar/bage &&
+ git push origin master
+ ) &&
+ (
+ cd work &&
+ git push --recurse-submodules=check ../pub.git master
+ )
+'
+
+test_expect_success 'push fails when commit on multiple branches if one branch has no remote' '
+ (
+ cd work/gar/bage &&
+ >junk4 &&
+ git add junk4 &&
+ git commit -m "Fourth junk"
+ ) &&
+ (
+ cd work &&
+ git branch branch2 &&
+ git add gar/bage &&
+ git commit -m "Fourth commit for gar/bage" &&
+ git checkout branch2 &&
+ (
+ cd gar/bage &&
+ git checkout HEAD~1
+ ) &&
+ >junk1 &&
+ git add junk1 &&
+ git commit -m "First junk" &&
+ test_must_fail git push --recurse-submodules=check ../pub.git
+ )
+'
+
+test_expect_success 'push succeeds if submodule has no remote and is on the first superproject commit' '
+ mkdir a &&
+ (
+ cd a &&
+ git init --bare
+ ) &&
+ git clone a a1 &&
+ (
+ cd a1 &&
+ mkdir b &&
+ (
+ cd b &&
+ git init &&
+ >junk &&
+ git add junk &&
+ git commit -m "initial"
+ ) &&
+ git add b &&
+ git commit -m "added submodule" &&
+ git push origin master
+ )
+'
+
+test_expect_success 'push succeeds when --no-recurse-submodules is used' '
+ (
+ cd work &&
+ git push ../pub.git --no-recurse-submodules
+ )
+'
+
test_done
diff --git a/transport.c b/transport.c
index c9c8056..9c100c9 100644
--- a/transport.c
+++ b/transport.c
@@ -10,6 +10,7 @@
#include "refs.h"
#include "branch.h"
#include "url.h"
+#include "submodule.h"
/* rsync support */
@@ -1041,6 +1042,14 @@ int transport_push(struct transport *transport,
flags & TRANSPORT_PUSH_MIRROR,
flags & TRANSPORT_PUSH_FORCE);
+ if ((flags & TRANSPORT_RECURSE_SUBMODULES_CHECK) && !is_bare_repository()) {
+ struct ref *ref = remote_refs;
+ for (; ref; ref = ref->next)
+ if (!is_null_sha1(ref->new_sha1) &&
+ check_for_unpushed_submodule_commits(ref->new_sha1))
+ die("There are unpushed submodules, aborting.");
+ }
+
push_ret = transport->push_refs(transport, remote_refs, flags);
err = push_had_errors(remote_refs);
ret = push_ret | err;
diff --git a/transport.h b/transport.h
index 161d724..059b330 100644
--- a/transport.h
+++ b/transport.h
@@ -101,6 +101,7 @@ struct transport {
#define TRANSPORT_PUSH_MIRROR 8
#define TRANSPORT_PUSH_PORCELAIN 16
#define TRANSPORT_PUSH_SET_UPSTREAM 32
+#define TRANSPORT_RECURSE_SUBMODULES_CHECK 64
#define TRANSPORT_SUMMARY_WIDTH (2 * DEFAULT_ABBREV + 3)
--
1.7.6.397.g23ae2.dirty
^ permalink raw reply related
* Re: [PATCH v3 1/1] bisect: add support for bisecting bare repositories
From: Junio C Hamano @ 2011-08-09 17:26 UTC (permalink / raw)
To: Jon Seymour; +Cc: git, chriscool, j6t, jnareb, jrnieder
In-Reply-To: <1312855914-610-1-git-send-email-jon.seymour@gmail.com>
Jon Seymour <jon.seymour@gmail.com> writes:
> This extension to js/bisect-no-checkout adds support for bisecting bare repositories.
>
> It does this by relaxing the requirement that git bisect is invoked in a repository with a working tree and by defaulting to --no-checkout in the case of a bare repository.
>
> Two tests are included to demonstrate this behaviour.
I'd wrap the long line myself but next time please be careful.
> diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh
> index 4fb7d11..62125ec 100755
> --- a/t/t6030-bisect-porcelain.sh
> +++ b/t/t6030-bisect-porcelain.sh
> @@ -592,6 +592,37 @@ test_expect_success 'erroring out when using bad path parameters' '
> grep "bad path parameters" error.txt
> '
>
> +test_expect_success 'test bisection on bare repo - --no-checkout specified' '
> + git clone --bare . bare.nocheckout &&
> + (
> + cd bare.nocheckout &&
> + git bisect start --no-checkout &&
> + git bisect good $HASH1 &&
> + git bisect bad $HASH4 &&
> + git bisect run eval \
> + "test \$(git rev-list BISECT_HEAD ^$HASH2 --max-count=1 | wc -l) = 0" \
> + >../nocheckout.log &&
> + git bisect reset
> + ) &&
> + grep "$HASH3 is the first bad commit" nocheckout.log
> +'
git-bisect does not have any cd_to_toplevel so with a working tree you can
run a bisection from a subdirectory, it seems. I wonder what would happen
if you did "cd bare.nocheckout/objects" or something silly like that.
Just wondering...
^ permalink raw reply
* Re: [PATCH] git-am: Document new --exclude=<file> option
From: Junio C Hamano @ 2011-08-09 17:20 UTC (permalink / raw)
To: maximilian attems; +Cc: git
In-Reply-To: <1312903268-19994-1-git-send-email-max@stro.at>
maximilian attems <max@stro.at> writes:
> diff --git a/Documentation/git-am.txt b/Documentation/git-am.txt
> index 6b1b5af..62c8e3c 100644
> --- a/Documentation/git-am.txt
> +++ b/Documentation/git-am.txt
> @@ -13,7 +13,8 @@ SYNOPSIS
> [--3way] [--interactive] [--committer-date-is-author-date]
> [--ignore-date] [--ignore-space-change | --ignore-whitespace]
> [--whitespace=<option>] [-C<n>] [-p<n>] [--directory=<dir>]
> - [--reject] [-q | --quiet] [--scissors | --no-scissors]
> + [--exclude=<file>] [--reject] [-q | --quiet]
> + [--scissors | --no-scissors]
Please do not say "<file>" here (and below). git-apply.txt documents this
as <path> and that is what the value of this parameter is.
^ permalink raw reply
* Re: [PATCH 2/2] test: cope better with use of return for errors
From: Jeff King @ 2011-08-09 15:36 UTC (permalink / raw)
To: Johannes Sixt
Cc: Jonathan Nieder, git, Michael J Gruber, Junio C Hamano,
Ævar Arnfjörð Bjarmason
In-Reply-To: <4E40F3EA.8020406@viscovery.net>
On Tue, Aug 09, 2011 at 10:46:34AM +0200, Johannes Sixt wrote:
> Am 8/8/2011 3:17, schrieb Jonathan Nieder:
> > +test_eval_ () {
> > + # This is a separate function because some tests use
> > + # "return" to end a test_expect_success block early.
> > + eval >&3 2>&4 "$*"
> > +}
> > +
> > test_run_ () {
> > test_cleanup=:
> > expecting_failure=$2
> > - eval >&3 2>&4 "$1"
> > + test_eval_ "$1"
> > eval_ret=$?
> >
> > if test -z "$immediate" || test $eval_ret = 0 || test -n "$expecting_failure"
> > then
> > - eval >&3 2>&4 "$test_cleanup"
> > + test_eval_ "$test_cleanup"
> > fi
> > if test "$verbose" = "t" && test -n "$HARNESS_ACTIVE"; then
> > echo ""
>
> This invalidates at least t3900.29, which accesses an unexpanded $3
> from the test script. The patch below fixes this case.
Hmm. Isn't t3900 already broken, even without this patch? It does
something like this:
foo() {
test_expect_success 'bar' 'echo $3'
}
That can't possibly access the third positional parameter of foo, as we
are already inside the test_expect_success function, no matter what
functions we call after that.
If there is any regression here, it would be that we used to get the
positional parameters of test_run_, and now we get them from test_eval_.
So accessing "$2" used to get us $expecting_failure, but now gets
nothing. I doubt it matters, and tests would be insane to rely on
something internal like that. If it did, the right fix would be:
- test_eval_ "$1"
+ test_eval_ "$@"
in test_run_.
So I don't see a problem in Jonathan's patches. But clearly t3900 is
poorly written and should be fixed.
But:
> diff --git a/t/t3900-i18n-commit.sh b/t/t3900-i18n-commit.sh
> index c06a5ee..3265fac 100755
> --- a/t/t3900-i18n-commit.sh
> +++ b/t/t3900-i18n-commit.sh
> @@ -136,6 +136,7 @@ done
> test_commit_autosquash_flags () {
> H=$1
> flag=$2
> + mopt=$3
> test_expect_success "commit --$flag with $H encoding" '
> git config i18n.commitencoding $H &&
> git checkout -b $H-$flag C0 &&
> @@ -147,7 +148,7 @@ test_commit_autosquash_flags () {
> git commit -a -m "intermediate commit" &&
> test_tick &&
> echo $H $flag >>F &&
> - git commit -a --$flag HEAD~1 $3 &&
> + git commit -a --$flag HEAD~1 $mopt &&
> E=$(git cat-file commit '$H-$flag' |
> sed -ne "s/^encoding //p") &&
> test "z$E" = "z$H" &&
> @@ -160,6 +161,6 @@ test_commit_autosquash_flags () {
>
> test_commit_autosquash_flags eucJP fixup
>
> -test_commit_autosquash_flags ISO-2022-JP squash '-m "squash message"'
> +test_commit_autosquash_flags ISO-2022-JP squash '-m squash_message'
Can't we just drop $3 here? I don't see how it's actually doing
anything. It makes us call:
git commit --squash HEAD~1 -m squash_message
instead of just:
git commit --squash HEAD~1
but then we never actually check to see that the included message
becomes part of the squashed commit, anyway.
Also, a side note. These tests put their shell snippet inside single
quotes. And then access the variables sometimes directly (assuming they
are left unchanged inside the test functions), and sometimes using
single quotes. Which actually places them outside the snippet's single
quotes, and expands them in place. Which happens to be OK because they
don't contain any spaces, but would otherwise pass extra arguments to
test_expect_success.
So it's not a bug, but it does look unintentional and poor style.
Anyway. Your patch is fine and sufficient to solve the problem. Those
were all just thoughtst I had while trying to figure out what the test
was actually trying to do.
-Peff
^ permalink raw reply
* [PATCH] git-am: Document new --exclude=<file> option
From: maximilian attems @ 2011-08-09 15:21 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, maximilian attems
--exclude is passed down to apply, document it as such.
Signed-off-by: maximilian attems <max@stro.at>
---
Documentation/git-am.txt | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
Had to break up a line, not sure if the chose way is the preferred.
Thank you.
diff --git a/Documentation/git-am.txt b/Documentation/git-am.txt
index 6b1b5af..62c8e3c 100644
--- a/Documentation/git-am.txt
+++ b/Documentation/git-am.txt
@@ -13,7 +13,8 @@ SYNOPSIS
[--3way] [--interactive] [--committer-date-is-author-date]
[--ignore-date] [--ignore-space-change | --ignore-whitespace]
[--whitespace=<option>] [-C<n>] [-p<n>] [--directory=<dir>]
- [--reject] [-q | --quiet] [--scissors | --no-scissors]
+ [--exclude=<file>] [--reject] [-q | --quiet]
+ [--scissors | --no-scissors]
[(<mbox> | <Maildir>)...]
'git am' (--continue | --skip | --abort)
@@ -87,6 +88,7 @@ default. You can use `--no-utf8` to override this.
-C<n>::
-p<n>::
--directory=<dir>::
+--exclude=<file>::
--reject::
These flags are passed to the 'git apply' (see linkgit:git-apply[1])
program that applies
--
1.7.5.4
^ permalink raw reply related
* Re: Cleaning up history with git rebase
From: pbegeland @ 2011-08-09 12:29 UTC (permalink / raw)
To: Michael Witten; +Cc: Ricky Egeland, git
In-Reply-To: <7b4a0f436505467fa042739da159e0f4-mfwitten@gmail.com>
On Sun, 07 Aug 2011 19:13:01 -0000, Michael Witten <mfwitten@gmail.com>
wrote:
> On Sat, 06 Aug 2011 23:59:50 -0000, Michael Witten wrote:
>
>>> On Fri, 05 Aug 2011 18:26:27 -0300, Patricia Egeland wrote:
>>>
>>> I'd be greatly appreciated if you are still willing to help.
>>
>> ... my original script is incredibly naive (to the point of
>> being incorrect).
>
> In particular, my use of `cherry-pick' doesn't make any sense
> for all but the most contrived case.
>
>> Fortunately, I've thought a bit more about it, and I have a much
>> better solution in the works, so please hold on just a bit longer
>> while I work out the kinks.
>
> Using `rebase' is not the right solution because it doesn't handle
> merges
> meaningfully and it also throws out information, especially when it
> does
> successfully flatten merges (something that my first script attempted
> to emulate, too).
>
> As I began figuring out the necessary bookkeeping required for
> achieving
> a cleaner history for your case, it occurred to me that
> `filter-branch'
> does indeed handle a lot of the details already.
>
> What follows is the new script, which I've tested fairly well this
> time,
> and it shouldn't give you any confusing output either:
>
> #!/bin/sh
>
> if b=$(git symbolic-ref -q HEAD); then
> git branch "${b#refs/heads/}-saved" || exit 1;
> fi
>
> workdir= git filter-branch -f --commit-filter '
>
> if [ $# -eq 1 ]; then
>
> if [ $(git ls-tree --name-only $1 | wc -l) -eq 0 ]; then
> echo # Possible abuse of internals
> else
> git commit-tree $@
> fi
>
> elif [ $# -eq 3 ]; then
>
> git_commit_non_empty_tree $@
>
> else
>
> tree=$1
> shift
>
> parents=
> while [ $# -gt 0 ]; do
> shift
> parents="$parents $1"
> shift
> done
>
> parents_independent=
> for parent in $(git merge-base --independent $parents); do
> parents_independent="$parents_independent -p $parent"
> done
>
> git_commit_non_empty_tree $tree $parents_independent
>
> fi
>
> ' HEAD
>
> That `workdir=' bit at the top simply exports the `workdir' variable
> for
> the duration of the `filter-branch' command, and it is a workaround
> for
> the following bug:
>
> Message-ID: <f06dd070abcc485e98c054ec3ee298f9-mfwitten@gmail.com>
> http://marc.info/?l=git&m=131268922806303&w=2
>
> In order to use this script, save it to a file (e.g. /tmp/s) and
> then:
>
> git checkout branch-to-clean
> sh /tmp/s
>
> That should save the messy history as a branch named
> `branch-to-clean-saved'
> and also leave the clean history behind in `branch-to-clean'.
>
> Now, you've been doing a lot of work with your subrepos, so please
> make
> sure that you're running the script on the right branch.
It worked perfectly, Michael. Like a charm.
I believe your script can become a great contribution to the git
community.
My merge commit messages reduced from 470 to 155. The history looks
very clean and organized.
Thanks a lot for all the time you spent helping us.
Best,
Patricia
>
> Sincerely,
> Michael Witten
>
> I built a test repository as follows (which requires a little manual
> intervention along the way, in that you must save commit messages by
> hand after the automatic conflict resolutions):
>
> #!/bin/sh
>
> git init test
> cd test
>
> printf A > foo
> printf A > bar
> git add .
> git commit -m A
> git branch A
>
> git checkout -b B_foo A
> printf B > foo
> git commit -am B_foo
>
> git checkout -b B_bar A
> printf B > bar
> git commit -am B_bar
>
> git checkout -b B_baz A
> printf B > baz
> git add baz
> git commit -m B_baz
>
> git checkout -b C A
> git merge --no-ff B_foo B_bar
>
> git checkout -b D C
> printf D > foo
> printf D > bar
> git commit -am D
>
> git checkout -b E_foo_0 D
> printf 0 > foo
> git commit -am E_foo_0
>
> git checkout -b E_foo_1 D
> printf 1 > foo
> git commit -am E_foo_1
>
> git checkout -b F D
> git merge --no-ff E_foo_0 E_foo_1 # Conflict.
> printf F > foo # Resolve.
> git commit -a # Commit (using the supplied
> message).
>
> git checkout -b G_foo_0 F
> printf 0 > foo
> git commit -am G_foo_0
>
> git checkout -b G_foo_1 F
> printf 1 > foo
> git commit -am G_foo_1
>
> git checkout -b G_quux G_foo_1
> printf G > quux
> git add quux
> git commit -m G_quux
>
> git checkout -b G_foo_2 G_quux
> printf 2 > foo
> git commit -am G_foo_2
>
> git checkout -b H G_foo_0
> git merge G_foo_2 # Conflict.
> printf G > foo # Resolve.
> git commit -a # Commit (using the supplied
> message).
>
> git checkout -b I H
> git merge --no-ff B_baz
>
> git checkout -b J I
> printf J > foo
> printf J > bar
> printf J > baz
> git commit -am J
>
> git checkout -b foo-only J
> git filter-branch -f --index-filter '
> git rm --cached --ignore-unmatch bar baz quux
> ' HEAD
>
> git checkout -b bar-only J
> git filter-branch -f --index-filter '
> git rm --cached --ignore-unmatch foo baz quux
> ' HEAD
>
> git checkout -b baz-only J
> git filter-branch -f --index-filter '
> git rm --cached --ignore-unmatch foo bar quux
> ' HEAD
>
> git checkout -b quux-only J
> git filter-branch -f --index-filter '
> git rm --cached --ignore-unmatch foo bar baz
> ' HEAD
>
> git checkout -b baz-quux-only J
> git filter-branch -f --index-filter '
> git rm --cached --ignore-unmatch foo bar
> ' HEAD
>
> The branches of importance here are:
>
> foo-only
> bar-only
> baz-only
> quux-only
> baz-quux-only
>
> Each is a slice of the 'big' branch `J', and each is reminiscent of
> one
> of your smaller subrepos.
>
> You'll notice that I didn't bother using `--prune-empty' when I
> created
> the slices, as the new script can handle empty commits better anyway
> (it accounts for merge commits, too). Thus, the result is that the
> history of each slice still has the same topology as 'big' branch
> `J',
> but many of the commits in that topology don't actually contribute
> any
> content.
>
> So, at this point, the graph of each of the branches in question all
> look the same in terms of the number of commits and the connections
> between them (the only difference is betweeen commit IDs, etc.). For
> instance, the unclean `baz-quux-only' history looks like this:
>
> $ git log baz-quux-only --graph --format='%s%ncommit: %H%ntree:
> %T%n%b%n'
> * J
> | commit: 26f3c0a6d026c8957439a52bf2d3e6955f627c82
> | tree: ffe9a251c0df24b955f2e5ebf3d10592052c985a
> |
> |
> * Merge branch 'B_baz' into I
> |\ commit: 9242bb70580a3bf11f20c8a2ab3fd277885739ad
> | | tree: 155fd83a71d531e1a0413dc4a475af4e72d471c2
> | |
> | |
> | * B_baz
> | | commit: b95287cda5d2ed5e8af100cd059ac9aef25d4369
> | | tree: e60c1f8cd2a0eccc2e4527aafa58865c37dc3ba9
> | |
> | |
> * | Merge branch 'G_foo_2' into H
> |\ \ commit: 9093055281c6f971b9fbdede06e03bd4824e42ef
> | | | tree: ff8ecc87699e099733f3145c4bb97466b0a9aec9
> | | | Conflicts:
> | | | foo
> | | |
> | | |
> | * | G_foo_2
> | | | commit: e9f3fd76023f0b3f32404b4123c541aa2acfef77
> | | | tree: ff8ecc87699e099733f3145c4bb97466b0a9aec9
> | | |
> | | |
> | * | G_quux
> | | | commit: 6eeb3f33f356558fd603afe9dc52331cad279805
> | | | tree: ff8ecc87699e099733f3145c4bb97466b0a9aec9
> | | |
> | | |
> | * | G_foo_1
> | | | commit: d33ca0afaa1a844fc84a2e7cba4bdd581a5794d4
> | | | tree: 4b825dc642cb6eb9a060e54bf8d69288fbee4904
> | | |
> | | |
> * | | G_foo_0
> |/ / commit: f2d083d0c92f1fca146893dd094daa5b2dfb73c0
> | | tree: 4b825dc642cb6eb9a060e54bf8d69288fbee4904
> | |
> | |
> | |
> | \
> *-. \ Merge branches 'E_foo_0' and 'E_foo_1' into F
> |\ \ \ commit: f6b0822ff36b35e6239fffddaa82750d3d9e2832
> | | | | tree: 4b825dc642cb6eb9a060e54bf8d69288fbee4904
> | | | | Conflicts:
> | | | | foo
> | | | |
> | | | |
> | | * | E_foo_1
> | |/ / commit: f1f4dddcd5de8bdf23f700b3267b20ce9f88c58c
> |/| | tree: 4b825dc642cb6eb9a060e54bf8d69288fbee4904
> | | |
> | | |
> | * | E_foo_0
> |/ / commit: dddb96a1b0b3659db3ed0245dc5c08d2d74855aa
> | | tree: 4b825dc642cb6eb9a060e54bf8d69288fbee4904
> | |
> | |
> * | D
> | | commit: 9d643ba07d58211211351c9e9266c5a9171965e8
> | | tree: 4b825dc642cb6eb9a060e54bf8d69288fbee4904
> | |
> | |
> | |
> | \
> *-. \ Merge branches 'B_foo' and 'B_bar' into C
> |\ \ \ commit: ed26df8f1192de9eae864f220dda35bbd53b8516
> | |_|/ tree: 4b825dc642cb6eb9a060e54bf8d69288fbee4904
> |/| |
> | | |
> | | * B_bar
> | |/ commit: 3202bd87d37ae084bee86158391489fc7c55002a
> |/| tree: 4b825dc642cb6eb9a060e54bf8d69288fbee4904
> | |
> | |
> | * B_foo
> |/ commit: 6088f291122686d6f06ab33082e77937d486b354
> | tree: 4b825dc642cb6eb9a060e54bf8d69288fbee4904
> |
> |
> * A
> commit: 104393c27f4ee7a1cbbdae17d21a2f478e8f723f
> tree: 4b825dc642cb6eb9a060e54bf8d69288fbee4904
>
> As you can see, there are a lot of commits there that are completely
> irrelevant.
>
> Assuming that the new script is stored as /tmp/s, then this history
> can be cleaned up as follows:
>
> git checkout baz-quux-only
> sh /tmp/s
>
> This should save the messy history as branch `baz-quux-only-saved'
> and
> also leave the following clean history behind in branch
> `baz-quux-only':
>
> $ git log baz-quux-only --graph --format='%s%ncommit: %H%ntree:
> %T%n%b%n'
> * J
> | commit: f460d134835ece09bab7b3584934930bc5abfb40
> | tree: ffe9a251c0df24b955f2e5ebf3d10592052c985a
> |
> |
> * Merge branch 'B_baz' into I
> |\ commit: 38da9ce07e6859b6cabadcaca1b2eed78c3f8cd5
> | | tree: 155fd83a71d531e1a0413dc4a475af4e72d471c2
> | |
> | |
> | * B_baz
> | commit: bd25181fd0c806a4495400cd13e21007e36c600b
> | tree: e60c1f8cd2a0eccc2e4527aafa58865c37dc3ba9
> |
> |
> * G_quux
> commit: 7c7080def8e2e000e9e9b1e9efc863155b8188e0
> tree: ff8ecc87699e099733f3145c4bb97466b0a9aec9
>
> Notice how even the root commits have been improved; there is now:
>
> * a root that creates the `quux' file.
> * a root that creates the `baz' file.
>
> and these 2 roots are merged together. There are no empty commits.
>
> Similarly, the unclean history for `foo-only' may be cleaned up as
> follows:
>
> git checkout foo-only
> sh /tmp/s
>
> producing the following history:
>
> $ git log foo-only --graph --format='%s%ncommit: %H%ntree:
> %T%n%b%n'
> * J
> | commit: 6c88a36c2bba348baea557687601a5337cf978c4
> | tree: 9e990d3e85287e21abe7b0b06f062fb9b16e769c
> |
> |
> * Merge branch 'G_foo_2' into H
> |\ commit: cdb5e89aad7b399bb8c7de5702350205158bdede
> | | tree: 0f149c5cc454a9d23e00d40819c25f49c90f682a
> | | Conflicts:
> | | foo
> | |
> | |
> | * G_foo_2
> | | commit: 861c76fb89846c4100c241e554123befdd074fa0
> | | tree: cfa452475c8f564b762ce25143cf905568c172a9
> | |
> | |
> | * G_foo_1
> | | commit: b8a3e5d6230c2312b6675e2b36deaa9310c5bd18
> | | tree: 0c6433b15dcd449d4d6acf053a18301d96b43fc0
> | |
> | |
> * | G_foo_0
> |/ commit: 8c0c515f0f9ec5994d4f8e5f244c3e869abb0384
> | tree: a39b4d0fdb82ee3da3e01875236754ef983f431b
> |
> |
> * Merge branches 'E_foo_0' and 'E_foo_1' into F
> |\ commit: be03f5a201d9fea098f733b9bb1d58d30e89ac9c
> | | tree: 8d5bb46eff3e15e67f77e2fc9ddb6be755df2b5b
> | | Conflicts:
> | | foo
> | |
> | |
> | * E_foo_1
> | | commit: ba04ecb0bac23315b5ef1e68d571487766ab017e
> | | tree: 0c6433b15dcd449d4d6acf053a18301d96b43fc0
> | |
> | |
> * | E_foo_0
> |/ commit: 676e381590a316d68b65c2c57d82f06d189e42c7
> | tree: a39b4d0fdb82ee3da3e01875236754ef983f431b
> |
> |
> * D
> | commit: 6ade1fbc6b41577c03bf38bfdb08e5fc8f8581e2
> | tree: 6a34a4b5b563e07707e3da3e9c39de796b4bf790
> |
> |
> * B_foo
> | commit: 8dd97d2a76ea2a07741b86064fd44e8da1170a7e
> | tree: 9712ce0451874e06403b4b60fe662ef2d111d8e5
> |
> |
> * A
> commit: 7d063cc6bd302f0c5d83bd7de3415397cf45cec8
> tree: 150d77852b97356b90e6a1cae8b62e85613637a1
>
> As you can see, the first merge commit has been completely flattened,
> the branching histories have been simplified by fast-forwading where
> possible, and non-contributing commits have been pruned.
>
> The rest of the cleaned histories follow:
>
> $ git log bar-only --graph --format='%s%ncommit: %H%ntree:
> %T%n%b%n'
> * J
> | commit: bc915e51a3619584adbe048a5002a9be26503d1b
> | tree: e175a92b6e4240caf24b6b8517ab184f5fbc2deb
> |
> |
> * D
> | commit: 7a5d0cf2761f430e8d2879b02476b1c2882f28d3
> | tree: a8710e5cbcfd7b411113eb0c8417a82c6214afa8
> |
> |
> * B_bar
> | commit: 18c5f8e0b0934577d7aa04cb8b3692b295503fe1
> | tree: b09152c27cc708366ee1d2e920adfc2faf021143
> |
> |
> * A
> commit: 6ed22455ae04e9e6fcd9a5001dd33703781d5d07
> tree: 3786d2ba9edc25dddab82eb87e53ebbee57a8dab
>
>
> $ git log baz-only --graph --format='%s%ncommit: %H%ntree:
> %T%n%b%n'
> * J
> | commit: 1a86f4d0424367e7e75ad45f60127ff4ad0e23dd
> | tree: 966dd81a7ee77d0b6da290769f22060fed665984
> |
> |
> * B_baz
> commit: bd25181fd0c806a4495400cd13e21007e36c600b
> tree: e60c1f8cd2a0eccc2e4527aafa58865c37dc3ba9
>
>
> $ git log quux-only --graph --format='%s%ncommit: %H%ntree:
> %T%n%b%n'
> * G_quux
> commit: 7c7080def8e2e000e9e9b1e9efc863155b8188e0
> tree: ff8ecc87699e099733f3145c4bb97466b0a9aec9
>
> As you can see, there are some amazing simplifications here.
^ permalink raw reply
* Re: git diff is slow (--patience is fast)
From: Marat Radchenko @ 2011-08-09 11:39 UTC (permalink / raw)
To: git
In-Reply-To: <CALUzUxpOR-YZh-GKzivyKVpff9ue-t3qEoNK4wGsZZjX_a1=-A@mail.gmail.com>
Good idea.
New steps to reproduce:
~ $ git clone git://slonopotamus.org/git-diff
Cloning into git-diff...
remote: Counting objects: 6, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 6 (delta 1), reused 0 (delta 0)
Receiving objects: 100% (6/6), 478.87 KiB | 722 KiB/s, done.
Resolving deltas: 100% (1/1), done.
~ $ cd git-diff
~/git-diff $ time git diff HEAD^ > /dev/null
real 0m6.585s
user 0m6.540s
sys 0m0.040s
~/git-diff $ time git diff --patience HEAD^ > /dev/null
real 0m0.259s
user 0m0.220s
sys 0m0.030s
^ permalink raw reply
* Re: git diff is slow (--patience is fast)
From: Tay Ray Chuan @ 2011-08-09 10:49 UTC (permalink / raw)
To: Marat Radchenko; +Cc: git
In-Reply-To: <loom.20110809T093124-847@post.gmane.org>
On Tue, Aug 9, 2011 at 3:51 PM, Marat Radchenko <marat@slonopotamus.org> wrote:
> Warning, downloaded files are 7.5Mb each.
I'm having some speed issues. Is it possible to make your repo
publicly available (eg github)? Perhaps the compression git does for
its objects could help make downloads zippier.
--
Cheers,
Ray Chuan
^ permalink raw reply
* Re: [PATCH v2 4/4] upload-archive: use start_command instead of fork
From: René Scharfe @ 2011-08-09 10:25 UTC (permalink / raw)
To: Jeff King; +Cc: Johannes Sixt, Erik Faye-Lund, Junio C Hamano, git
In-Reply-To: <20110809050211.GA3588@sigill.intra.peff.net>
Am 09.08.2011 07:02, schrieb Jeff King:
> On Mon, Aug 08, 2011 at 07:10:01PM +0200, René Scharfe wrote:
>
>>> - tar_filter_config("tar.tgz.command", "gzip -cn", NULL);
>>> + tar_filter_config("tar.tgz.command", "gzip -cn | cat", NULL);
>>> tar_filter_config("tar.tgz.remote", "true", NULL);
>>> - tar_filter_config("tar.tar.gz.command", "gzip -cn", NULL);
>>> + tar_filter_config("tar.tar.gz.command", "gzip -cn | cat", NULL);
>>> tar_filter_config("tar.tar.gz.remote", "true", NULL);
>>> git_config(git_tar_config, NULL);
>>> for (i = 0; i < nr_tar_filters; i++) {
>>>
>>> (provided that 'cat' magically does not suffer from the same problem,
>>> and I do think that it does not.)
>>
>> The external cat can indeed be used. We'd need to do that for user
>> supplied commands as well, though, like this (ugh):
>>
>> diff --git a/archive-tar.c b/archive-tar.c
>> index 20af005..eaa9a1c 100644
>> --- a/archive-tar.c
>> +++ b/archive-tar.c
>> @@ -326,6 +326,9 @@ static int write_tar_filter_archive(const struct archiver *ar,
>> die("BUG: tar-filter archiver called with no filter defined");
>>
>> strbuf_addstr(&cmd, ar->data);
>> +#ifdef WIN32
>> + strbuf_addstr(&cmd, " | cat");
>> +#endif
>> if (args->compression_level >= 0)
>> strbuf_addf(&cmd, " -%d", args->compression_level);
>
> Do we need to? It seems to me that defaulting to "gzip -cn | cat" is not
> "we are on Windows, a platform that needs a special workaround in git",
> but rather "this gzip is horribly broken, but at build-time you can
> set a gzip that works".
It's an MSYS platform problem IMHO, and we can work around it. That
extra cat is nothing to be proud of, sure. And msysgit avoiding the
issue by distibuting a gzip that never converts line endings would solve
it without any runtime overhead.
> So if the user wants to specify some broken filter, it is up to them to
> add "| cat" if their filter merits it.
Well, I'd rather take this responsibility from the user, who might
struggle a while before finding out what is going on. However...
> But that is somewhat a matter of perception, and it won't make a user on
> Windows who does "git config archive.bz2 bzip2 -c" any happier when they
> are told it is their responsibility to deal with it.
If all packers shipped with msysgit are usable then we're probably good.
> BTW, as nice as this "gzip -cn | cat" idea is, I think it needs to be
> wrapped in a shell script. With the code above, we will generate "gzip
> -cn | cat -9".
Yes, the three added lines in the patch above would have to be moved
down two lines, after the compression level is added. D'oh!
> So we really need:
>
> $ cat `which gzip`
> #!/bin/sh
> gzip.real -cn "$@" | cat
>
> and then no hacks need to go into git at all. The fix is about providing
> a sane gzip, not fixing git.
OK, that's one way to do it; another would be let gzip (and bzip2 etc.)
do whatever cat does to avoid end of line conversions. And yet another
is to take them from http://unxutils.sourceforge.net/.
> BTW, from what Johannes said, the issue is about a non-msys program
> calling an msys one. Does that mean that having git run:
>
> sh -c 'gzip -cn'
>
> would work? If so, then could the solution be as simple as turning off
> the "don't bother with the shell" optimization that run-command uses?
> Something like "gzip -cn" gets split by git and run via spawn now
> (because it has no metacharacters). But we could easily make it always
> run through the shell.
Just checked -- it doesn't work. I assume that's because the shell is
also an MSYS program.
René
^ permalink raw reply
* Suggestion: improve cherry-pick message in case object is not found
From: Piotr Krukowiecki @ 2011-08-09 9:58 UTC (permalink / raw)
To: Git Mailing List
Hi,
I'd like to suggest improving message displayed by cherry-pick (and
others?) when it's given non-existing sha1. For example:
$ git cherry-pick 2ac2d6d5997de01b84de54fe8ac5c7d6bba139ca
fatal: bad object 2ac2d6d5997de01b84de54fe8ac5c7d6bba139ca
The "fatal: bad object" suggest to me that the object is found but is
incorrect/corrupted. It took me some time (in which I managed to run
git fsck) to find out that I ran this git on wrong repository, which
did not have object with this sha1.
Is it possible to change this message to for example:
fatal: could not find object 2ac2d6d5997de01b84de54fe8ac5c7d6bba139ca
Thanks,
--
Piotr Krukowiecki
^ permalink raw reply
* Re: [PATCH 2/2] test: cope better with use of return for errors
From: Johannes Sixt @ 2011-08-09 8:46 UTC (permalink / raw)
To: Jonathan Nieder
Cc: git, Michael J Gruber, Junio C Hamano, Jeff King,
Ævar Arnfjörð Bjarmason
In-Reply-To: <20110808011709.GC19551@elie.gateway.2wire.net>
Am 8/8/2011 3:17, schrieb Jonathan Nieder:
> +test_eval_ () {
> + # This is a separate function because some tests use
> + # "return" to end a test_expect_success block early.
> + eval >&3 2>&4 "$*"
> +}
> +
> test_run_ () {
> test_cleanup=:
> expecting_failure=$2
> - eval >&3 2>&4 "$1"
> + test_eval_ "$1"
> eval_ret=$?
>
> if test -z "$immediate" || test $eval_ret = 0 || test -n "$expecting_failure"
> then
> - eval >&3 2>&4 "$test_cleanup"
> + test_eval_ "$test_cleanup"
> fi
> if test "$verbose" = "t" && test -n "$HARNESS_ACTIVE"; then
> echo ""
This invalidates at least t3900.29, which accesses an unexpanded $3
from the test script. The patch below fixes this case.
I tried to detect other cases by poisoning test_run_ like this:
- test_eval_ "$1"
+ test_eval_ :\; :\; :\; :\; :\; "$1"
in the hopes that ":;" is an error at the place that uses $1, $2, etc.
t3900.2[89] are the only tests that are uncovered in this way.
I noticed this because I have a patched test-lib.sh that calls
test_eval_ in a similarly modified manner.
--- >8 ---
From: Johannes Sixt <j6t@kdbg.org>
Subject: [PATCH] t3900: do not reference numbered arguments from the test
script
The call to test_expect_success is nested inside a function, whose
arguments the test code wants to access. But it is not specified that any
unexpanded $1, $2, $3, etc in the test code will access the surrounding
function's arguments. Rather, they will access the arguments of the
function that happens to eval the test code.
Play safe by placing the argument in a named variable.
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
---
t/t3900-i18n-commit.sh | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/t/t3900-i18n-commit.sh b/t/t3900-i18n-commit.sh
index c06a5ee..3265fac 100755
--- a/t/t3900-i18n-commit.sh
+++ b/t/t3900-i18n-commit.sh
@@ -136,6 +136,7 @@ done
test_commit_autosquash_flags () {
H=$1
flag=$2
+ mopt=$3
test_expect_success "commit --$flag with $H encoding" '
git config i18n.commitencoding $H &&
git checkout -b $H-$flag C0 &&
@@ -147,7 +148,7 @@ test_commit_autosquash_flags () {
git commit -a -m "intermediate commit" &&
test_tick &&
echo $H $flag >>F &&
- git commit -a --$flag HEAD~1 $3 &&
+ git commit -a --$flag HEAD~1 $mopt &&
E=$(git cat-file commit '$H-$flag' |
sed -ne "s/^encoding //p") &&
test "z$E" = "z$H" &&
@@ -160,6 +161,6 @@ test_commit_autosquash_flags () {
test_commit_autosquash_flags eucJP fixup
-test_commit_autosquash_flags ISO-2022-JP squash '-m "squash message"'
+test_commit_autosquash_flags ISO-2022-JP squash '-m squash_message'
test_done
--
1.7.6.1618.gc932c
^ permalink raw reply related
* git diff is slow (--patience is fast)
From: Marat Radchenko @ 2011-08-09 7:51 UTC (permalink / raw)
To: git
Warning, downloaded files are 7.5Mb each.
~ $ git --version
git version 1.7.6
~ $ mkdir tmp
~ $ cd tmp
~/tmp $ git init
Initialized empty Git repository in /home/marat/tmp/.git/
~/tmp $ wget http://slonopotamus.org/git-diff/foo 2> /dev/null
~/tmp $ git add -A
~/tmp $ git commit -am "initial"
[master (root-commit) 6b68e83] initial
1 files changed, 410461 insertions(+), 0 deletions(-)
create mode 100644 foo
~/tmp $ wget http://slonopotamus.org/git-diff/foo2 -O foo 2> /dev/null
~/tmp $ time git diff > /dev/null
real 0m6.513s
user 0m6.490s
sys 0m0.020s
~/tmp $ time git diff --patience > /dev/null
real 0m0.237s
user 0m0.180s
sys 0m0.050s
Could something be done to `git diff` speed? I would be happy with patience
diff, but other git commands call standard diff algorithm internally without
giving an option to choose patience.
gprof output against git master:
http://slonopotamus.org/git-diff/gmon.txt
^ permalink raw reply
* Re: Suppressing auto-cc for specific addresses
From: Daniel Mack @ 2011-08-09 7:40 UTC (permalink / raw)
To: Jeff King; +Cc: Jonathan Nieder, David Aguilar, Greg KH, git
In-Reply-To: <20110809070141.GA13623@sigill.intra.peff.net>
On Tue, Aug 9, 2011 at 9:01 AM, Jeff King <peff@peff.net> wrote:
> On Mon, Aug 08, 2011 at 11:07:14PM +0200, Jonathan Nieder wrote:
>
>> > I'm kind of confused why you would mark an address as "cc", but not cc
>> > it. Wouldn't it make sense to call the header something else?
>>
>> Maybe the patch is a draft and he is seeking early feedback. The
>> final version will be cc-ed to the indicated person later (and that's
>> part of what it is time to get feedback on).
>
> I suspect in that workflow, you would use --suppress-cc=all, and then
> just address it to whomever you are getting feedback from.
>
>> Or maybe the Cc: line is from the original patch and he is using git
>> send-email to forward it without mangling.
>
> In that case, shouldn't the cc either be respected (since the original
> patch author wanted it so), or stripped (if the patch no longer has
> anything to do with that cc).
>
>
> Still, we are only guessing at possible workflows here. I don't have a
> problem with the idea of per-address suppression; it makes git more
> flexible and doesn't hurt people who don't need the flexibility.
>
> I was more objecting to it as a solution to a workflow that is "we want
> a unique tag in the commit, so we called it 'cc', but don't want people
> to actually 'cc' it". That's just wrong and silly. But it turns out that
> isn't happening here, anyway.
Right. I thought I might fix something here to improve a widely
anticipated workflow, but as it turns out, it's not actually needed. I
don't personally have any other use for this feature, so I don't care
much whether it will be applied eventually. Except for the fact that
it would be my first contribution to git, of course ;)
So - up to you to decide.
Thanks,
Daniel
^ permalink raw reply
* Re: [PATCH 26/48] merge-recursive: Allow make_room_for_path() to remove D/F entries
From: Johannes Sixt @ 2011-08-09 7:01 UTC (permalink / raw)
To: Elijah Newren; +Cc: git, jgfouca
In-Reply-To: <CABPp-BEBJnMCwKKL67=LkB8pea+7QkpoXih3P7rfF5AiDRQYZQ@mail.gmail.com>
Am 8/8/2011 22:56, schrieb Elijah Newren:
> Hi,
>
> On Wed, Jul 13, 2011 at 1:17 AM, Johannes Sixt <j.sixt@viscovery.net> wrote:
>> Am 6/8/2011 9:30, schrieb Elijah Newren:
>>> +static int make_room_for_path(const struct merge_options *o, const char *path)
>>> {
>>> - int status;
>>> + int status, i;
>>> const char *msg = "failed to create path '%s'%s";
>>>
>>> + /* Unlink any D/F conflict files that are in the way */
>>> + for (i = 0; i < o->df_conflict_file_set.nr; i++) {
>>> + const char *df_path = o->df_conflict_file_set.items[i].string;
>>> + size_t pathlen = strlen(path);
>>> + size_t df_pathlen = strlen(df_path);
>>> + if (df_pathlen < pathlen && strncmp(path, df_path, df_pathlen) == 0) {
>>> + unlink(df_path);
>>> + break;
>>> + }
>>> + }
>>
>> Each time this loop is entered it tries to remove the same path again,
>> even if it does not exist anymore or was morphed into a directory in the
>> meantime. I suggest to remove a path from o->df_conflict_file_set after it
>> was unlinked. Or even better: have a separate "make room" phase somewhere
>> in the merge process.
>
> Removing it from o->df_conflict_file_set makes sense. However, there
> appears to be no API in string_list.h for deleting entries. Are such
> operations discouraged? I'm not sure whether to add such API, just
> hack it directly, or wait for someone else to come along and change
> this to a better data structure (such as a hash)...
>
> I don't think it's possible to move this "make room" phase anywhere
> earlier in the merge process. When we have D/F conflicts, the files
> of those D/F conflicts should only be removed if at least one of the
> paths under the corresponding directory are not removed by the merge
> process. We don't know whether those paths will need to be removed
> until we call process_entry() on each of them, and from there we go
> right to this function when we find one that needs to stick around.
> So I simply don't see how to move it any earlier.
I missed that the loop is selective: It removes only a subset of the
paths. Without a deeper understanding of the merge machinery I'll just
accept what you explain. Removing the paths from the list that were
unlinked seems to be the right approach.
Here's an attempt for a delete_item API (note: only compile-tested).
Bike-shed painters welcome: delete_item, remove_item, free_item?
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
diff --git a/Documentation/technical/api-string-list.txt b/Documentation/technical/api-string-list.txt
index 3f575bd..ce24eb9 100644
--- a/Documentation/technical/api-string-list.txt
+++ b/Documentation/technical/api-string-list.txt
@@ -29,6 +29,9 @@ member (you need this if you add things later) and you should set the
. Can sort an unsorted list using `sort_string_list`.
+. Can remove individual items of an unsorted list using
+ `unsorted_string_list_delete_item`.
+
. Finally it should free the list using `string_list_clear`.
Example:
@@ -112,6 +115,13 @@ write `string_list_insert(...)->util = ...;`.
The above two functions need to look through all items, as opposed to their
counterpart for sorted lists, which performs a binary search.
+`unsorted_string_list_delete_item`::
+
+ Remove an item from a string_list. The `string` pointer of the items
+ will be freed in case the `strdup_strings` member of the string_list
+ is set. The third parameter controls if the `util` pointer of the
+ items should be freed or not.
+
Data structures
---------------
diff --git a/string-list.c b/string-list.c
index 5168118..d9810ab 100644
--- a/string-list.c
+++ b/string-list.c
@@ -185,3 +185,12 @@ int unsorted_string_list_has_string(struct string_list *list,
return unsorted_string_list_lookup(list, string) != NULL;
}
+void unsorted_string_list_delete_item(struct string_list *list, int i, int free_util)
+{
+ if (list->strdup_strings)
+ free(list->items[i].string);
+ if (free_util)
+ free(list->items[i].util);
+ list->items[i] = list->items[list->nr-1];
+ list->nr--;
+}
diff --git a/string-list.h b/string-list.h
index bda6983..0684cb7 100644
--- a/string-list.h
+++ b/string-list.h
@@ -44,4 +44,5 @@ void sort_string_list(struct string_list *list);
int unsorted_string_list_has_string(struct string_list *list, const char *string);
struct string_list_item *unsorted_string_list_lookup(struct string_list *list,
const char *string);
+void unsorted_string_list_delete_item(struct string_list *list, int i, int free_util);
#endif /* STRING_LIST_H */
> [...]
>
> However, I don't see how any of this would address any failure you're
> seeing on windows. Maybe one of my other changes, including one or
> two other bugfixes I've found will help? I'll have to ping you when I
> submit the re-roll.
I stumbled over this only because on Windows we have an implementation of
unlink() that asks whether to retry a failed unlink attempt. I was using
an old version that asks when a directory was tried to unlink where a
retry is pointless.
-- Hannes
^ permalink raw reply related
* Re: Suppressing auto-cc for specific addresses
From: Jeff King @ 2011-08-09 7:01 UTC (permalink / raw)
To: Jonathan Nieder; +Cc: Daniel Mack, David Aguilar, Greg KH, git
In-Reply-To: <20110808210714.GA16512@elie.gateway.2wire.net>
On Mon, Aug 08, 2011 at 11:07:14PM +0200, Jonathan Nieder wrote:
> > I'm kind of confused why you would mark an address as "cc", but not cc
> > it. Wouldn't it make sense to call the header something else?
>
> Maybe the patch is a draft and he is seeking early feedback. The
> final version will be cc-ed to the indicated person later (and that's
> part of what it is time to get feedback on).
I suspect in that workflow, you would use --suppress-cc=all, and then
just address it to whomever you are getting feedback from.
> Or maybe the Cc: line is from the original patch and he is using git
> send-email to forward it without mangling.
In that case, shouldn't the cc either be respected (since the original
patch author wanted it so), or stripped (if the patch no longer has
anything to do with that cc).
Still, we are only guessing at possible workflows here. I don't have a
problem with the idea of per-address suppression; it makes git more
flexible and doesn't hurt people who don't need the flexibility.
I was more objecting to it as a solution to a workflow that is "we want
a unique tag in the commit, so we called it 'cc', but don't want people
to actually 'cc' it". That's just wrong and silly. But it turns out that
isn't happening here, anyway.
-Peff
^ permalink raw reply
* Re: What's cooking in git.git (Aug 2011, #02; Mon, 8)
From: Ramkumar Ramachandra @ 2011-08-09 5:36 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7v8vr3v7az.fsf@alter.siamese.dyndns.org>
Hi Junio,
Junio C Hamano writes:
> * rr/revert-cherry-pick-continue (2011-08-08) 18 commits
> [...]
> Getting into a reasonable shape. Is another round of re-roll coming?
I certainly have no plans of re-rolling. Although there are times I
wish I'd done a few things slightly differently while developing the
new series (on top of rr/revert-cherry-pick-continue), I'll refrain
from making any changes to this series. That little ugliness is the
price we have to pay for my lack of experience :) All the recent
reviews have mainly pointed out nits, and I really don't think there
are any other urgent issues with this series.
Thanks.
-- Ram
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox