* Re: [PATCH 2/2] Remember and use GIT_EXEC_PATH on exec()'s
From: Michal Ostrowski @ 2006-01-10 20:31 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Junio C Hamano, Andreas Ericsson, git
In-Reply-To: <Pine.LNX.4.63.0601102054200.27363@wbgn013.biozentrum.uni-wuerzburg.de>
On Tue, 2006-01-10 at 20:55 +0100, Johannes Schindelin wrote:
> Hi,
>
> On Tue, 10 Jan 2006, Junio C Hamano wrote:
>
> > Michal Ostrowski <mostrows@watson.ibm.com> writes:
> >
> > > git programs exec other git programs, but they also exec non-git
> > > programs. I think it is not appropriate to change PATH (via
> > > prepend_to_path) because this may result in unexpected behavior when
> > > exec'ing non-git programs:
> >
> > This is a valid concern.
>
> Why? If what is prepended to PATH only contains git programs?
>
If git is installed with prefix=/usr, then that won't be the case.
--
Michal Ostrowski <mostrows@watson.ibm.com>
^ permalink raw reply
* Re: git pull on Linux/ACPI release tree
From: Linus Torvalds @ 2006-01-10 20:28 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0601101151090.4939@g5.osdl.org>
On Tue, 10 Jan 2006, Linus Torvalds wrote:
>
> If a _different_ bug was introduced (even if it had the same effects),
> yes, you now have two separate bugs. And bisecting two bugs is hard. You
> need to separate them out some way.
Side note: this is seldom a problem in practice. If it was effectively the
same bug, just finding the one case that triggered it is sufficient: you
then know what to look for, and if undoing that one commit isn't enough to
fix it in the current tree (because the same bug existed in another form
on another branch), you wouldn't actually start bisecting again. You'd
start grepping the tree for other cases of that bug.
So the biggest advantage of "git bisect" is _not_ that you can just undo
the buggy commit. In fact, usually you don't even want to undo it, because
it probably had a raison-d'etre to begin with. The huge deal about "git
bisect" is that it pinpoints what caused the bug, and then the fix is
often something else.
Often it's a "Duh! I fixed one thing, but my fix didn't take Xyz into
account, so it now broke for another reason" moment.
Most bugs are stupid, in other words.
The _real_ problem with git bisect is when you have a non-technical user
(common) and there are silly bugs that you know of and already fixed that
aren't really a problem, but that are show-stoppers for the user who isn't
a kernel developer (or is, but doesn't know git). They're show-stoppers
not because we care about them, but because they make the "purely
mechanical" thing be one where you have to have some manual input.
Another problem (that I've not seen in practice yet, but that I bet _will_
be the worst issue) is non-reproducible bugs. They are the nastiest kind
to debug in the first place, and sadly, "git bisect" simply doesn't help
you with them. There, nothing but some luck and a lot of thinking and
testing will help you.
Linus
^ permalink raw reply
* Re: [PATCH 2/2] Remember and use GIT_EXEC_PATH on exec()'s
From: Michal Ostrowski @ 2006-01-10 20:29 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Andreas Ericsson, git
In-Reply-To: <7vu0cb6f1n.fsf@assigned-by-dhcp.cox.net>
On Tue, 2006-01-10 at 11:47 -0800, Junio C Hamano wrote:
> > No. git prepends whatever was passed in --exec-path=/some/path, what's
> > found in $GIT_EXEC_PATH or the GIT_EXEC_PATH pre-processor macro set
> > at compile-time, in that order of preference. There's a very big
> > difference.
>
> True.
>
> > Good point. Perhaps we should only prepend to path when the directory
> > isn't already in $PATH, or append rather than prepend.
>
> I think appending not prepending would stop letting me say
>
> $ GIT_EXEC_PATH=/usr/libexec/git-core/0.99.9k git foo
>
> to try out older version, if I have more recent git in my PATH.
> But I agree with Michal it is not nice to affect invocations of
> "diff" (and things spawned from hooks, which would inherit PATH
> from receive-pack).
>
>
How about searching for executables in the following places, and in this
order:
1. --exec-path setting, if any
2. GIT_EXEC_PATH env var, if set
3. PATH (never modified)
4. Value of ${bindir} at build time
To accomplish this I'd suggest reworking the logic the git c programs
use to exec another git program. The patch I sent out this morning
attempts to do this. (I'll append again to avoid confusion with
previous patches.) But note that the patch below doesn't implement this
policy above; the point is that it provides for a single location where
it has to be implemented (in exec_cmd.c). I'd be happy to clean it up
and submit it formally as a clean-up patch (one that doesn't change the
PATH/GIT_EXEC_PATH search behavior currently implemented).
Secondly, the shell scripts as is cannot utilize this search order as
long as they don't religiously use the git potty internally. If we were
to "sed -e 's/git-/git /g' -i git*.sh" (grotesquely simplified of
course) then they would.
--
Michal Ostrowski <mostrows@watson.ibm.com>
diff --git a/Makefile b/Makefile
index c9c15b5..db57858 100644
--- a/Makefile
+++ b/Makefile
@@ -173,7 +173,7 @@ DIFF_OBJS = \
LIB_OBJS = \
blob.o commit.o connect.o count-delta.o csum-file.o \
- date.o diff-delta.o entry.o ident.o index.o \
+ date.o diff-delta.o entry.o exec_cmd.o ident.o index.o \
object.o pack-check.o patch-delta.o path.o pkt-line.o \
quote.o read-cache.o refs.o run-command.o \
server-info.o setup.o sha1_file.o sha1_name.o strbuf.o \
@@ -184,6 +184,16 @@ LIB_OBJS = \
LIBS = $(LIB_FILE)
LIBS += -lz
+
+# .exec_cmd.bindir stores $(bindir) used to compile exec_cmd.o
+# If it has changed, store the new value and force exec_cmd.o to be
rebuilt
+ifneq ($(shell cat .exec_cmd.bindir 2>/dev/null),$(bindir))
+.PHONY: exec_cmd.c
+$(shell echo $(bindir) > .exec_cmd.bindir)
+endif
+
+exec_cmd.o: CFLAGS+=-DGIT_EXEC_PATH=\"$(bindir)\"
+
# Shell quote;
# Result of this needs to be placed inside ''
shq = $(subst ','\'',$(1))
diff --git a/daemon.c b/daemon.c
index 3bd1426..ab793bd 100644
--- a/daemon.c
+++ b/daemon.c
@@ -9,6 +9,7 @@
#include <syslog.h>
#include "pkt-line.h"
#include "cache.h"
+#include "exec_cmd.h"
static int log_syslog;
static int verbose;
@@ -227,7 +228,7 @@ static int upload(char *dir)
snprintf(timeout_buf, sizeof timeout_buf, "--timeout=%u", timeout);
/* git-upload-pack only ever reads stuff, so this is safe */
- execlp("git-upload-pack", "git-upload-pack", "--strict", timeout_buf,
".", NULL);
+ exec_git_cmd("upload-pack", "--strict", timeout_buf, ".");
return -1;
}
diff --git a/fetch-clone.c b/fetch-clone.c
index f46fe6e..5ae9bda 100644
--- a/fetch-clone.c
+++ b/fetch-clone.c
@@ -1,4 +1,5 @@
#include "cache.h"
+#include "exec_cmd.h"
#include <sys/wait.h>
static int finish_pack(const char *pack_tmp_name, const char *me)
@@ -27,8 +28,7 @@ static int finish_pack(const char *pack_
dup2(pipe_fd[1], 1);
close(pipe_fd[0]);
close(pipe_fd[1]);
- execlp("git-index-pack","git-index-pack",
- "-o", idx, pack_tmp_name, NULL);
+ exec_git_cmd("index-pack", "-o", idx, pack_tmp_name);
error("cannot exec git-index-pack <%s> <%s>",
idx, pack_tmp_name);
exit(1);
@@ -105,8 +105,7 @@ int receive_unpack_pack(int fd[2], const
dup2(fd[0], 0);
close(fd[0]);
close(fd[1]);
- execlp("git-unpack-objects", "git-unpack-objects",
- quiet ? "-q" : NULL, NULL);
+ exec_git_cmd("unpack-objects", quiet ? "-q" : NULL);
die("git-unpack-objects exec failed");
}
close(fd[0]);
diff --git a/git.c b/git.c
index 5e7da74..a45dc54 100644
--- a/git.c
+++ b/git.c
@@ -10,6 +10,7 @@
#include <stdarg.h>
#include <sys/ioctl.h>
#include "git-compat-util.h"
+#include "exec_cmd.h"
#ifndef PATH_MAX
# define PATH_MAX 4096
@@ -192,25 +193,6 @@ static void cmd_usage(const char *exec_p
exit(1);
}
-static void prepend_to_path(const char *dir, int len)
-{
- char *path, *old_path = getenv("PATH");
- int path_len = len;
-
- if (!old_path)
- old_path = "/usr/local/bin:/usr/bin:/bin";
-
- path_len = len + strlen(old_path) + 1;
-
- path = malloc(path_len + 1);
-
- memcpy(path, dir, len);
- path[len] = ':';
- memcpy(path + len + 1, old_path, path_len - len);
-
- setenv("PATH", path, 1);
-}
-
static void show_man_page(char *git_cmd)
{
char *page;
@@ -233,14 +215,10 @@ int main(int argc, char **argv, char **e
{
char git_command[PATH_MAX + 1];
char wd[PATH_MAX + 1];
- int i, len, show_help = 0;
- char *exec_path = getenv("GIT_EXEC_PATH");
+ int i, show_help = 0;
getcwd(wd, PATH_MAX);
- if (!exec_path)
- exec_path = GIT_EXEC_PATH;
-
for (i = 1; i < argc; i++) {
char *arg = argv[i];
@@ -257,9 +235,9 @@ int main(int argc, char **argv, char **e
if (!strncmp(arg, "exec-path", 9)) {
arg += 9;
if (*arg == '=')
- exec_path = arg + 1;
+ git_set_exec_path(arg + 1);
else {
- puts(exec_path);
+ puts(git_exec_path());
exit(0);
}
}
@@ -275,48 +253,18 @@ int main(int argc, char **argv, char **e
if (i >= argc || show_help) {
if (i >= argc)
- cmd_usage(exec_path, NULL);
+ cmd_usage(git_exec_path(), NULL);
show_man_page(argv[i]);
}
- if (*exec_path != '/') {
- if (!getcwd(git_command, sizeof(git_command))) {
- fprintf(stderr,
- "git: cannot determine current directory\n");
- exit(1);
- }
- len = strlen(git_command);
-
- /* Trivial cleanup */
- while (!strncmp(exec_path, "./", 2)) {
- exec_path += 2;
- while (*exec_path == '/')
- exec_path++;
- }
- snprintf(git_command + len, sizeof(git_command) - len,
- "/%s", exec_path);
- }
- else
- strcpy(git_command, exec_path);
- len = strlen(git_command);
- prepend_to_path(git_command, len);
-
- len += snprintf(git_command + len, sizeof(git_command) - len,
- "/git-%s", argv[i]);
- if (sizeof(git_command) <= len) {
- fprintf(stderr, "git: command name given is too long.\n");
- exit(1);
- }
-
- /* execve() can only ever return if it fails */
- execve(git_command, &argv[i], envp);
+ execv_git_cmd(argv + i);
if (errno == ENOENT)
- cmd_usage(exec_path, "'%s' is not a git-command", argv[i]);
+ cmd_usage(git_exec_path(), "'%s' is not a git-command",
+ argv[i]);
fprintf(stderr, "Failed to run command '%s': %s\n",
git_command, strerror(errno));
-
return 1;
}
diff --git a/receive-pack.c b/receive-pack.c
index f847ec2..8e78e32 100644
--- a/receive-pack.c
+++ b/receive-pack.c
@@ -257,7 +257,7 @@ static void read_head_info(void)
static const char *unpack(int *error_code)
{
- int code = run_command(unpacker, NULL);
+ int code = run_command_v_opt(1, &unpacker, RUN_GIT_CMD);
*error_code = 0;
switch (code) {
diff --git a/run-command.c b/run-command.c
index 8bf5922..b3d287e 100644
--- a/run-command.c
+++ b/run-command.c
@@ -1,6 +1,7 @@
#include "cache.h"
#include "run-command.h"
#include <sys/wait.h>
+#include "exec_cmd.h"
int run_command_v_opt(int argc, char **argv, int flags)
{
@@ -13,9 +14,13 @@ int run_command_v_opt(int argc, char **a
int fd = open("/dev/null", O_RDWR);
dup2(fd, 0);
dup2(fd, 1);
- close(fd);
+ close(fd);
+ }
+ if (flags & RUN_GIT_CMD) {
+ execv_git_cmd(argv);
+ } else {
+ execvp(argv[0], (char *const*) argv);
}
- execvp(argv[0], (char *const*) argv);
die("exec %s failed.", argv[0]);
}
for (;;) {
diff --git a/run-command.h b/run-command.h
index 2469eea..ef3ee05 100644
--- a/run-command.h
+++ b/run-command.h
@@ -12,7 +12,7 @@ enum {
};
#define RUN_COMMAND_NO_STDIO 1
-
+#define RUN_GIT_CMD 2 /*If this is to be git sub-command */
int run_command_v_opt(int argc, char **argv, int opt);
int run_command_v(int argc, char **argv);
int run_command(const char *cmd, ...);
diff --git a/shell.c b/shell.c
index cd31618..0d4891f 100644
--- a/shell.c
+++ b/shell.c
@@ -12,7 +12,7 @@ static int do_generic_cmd(const char *me
my_argv[1] = arg;
my_argv[2] = NULL;
- return execvp(me, (char**) my_argv);
+ return execv_git_cmd((char**) my_argv);
}
static struct commands {
diff --git a/upload-pack.c b/upload-pack.c
index 1834b6b..6602d68 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -4,6 +4,7 @@
#include "tag.h"
#include "object.h"
#include "commit.h"
+#include "exec_cmd.h"
static const char upload_pack_usage[] = "git-upload-pack [--strict]
[--timeout=nn] <dir>";
@@ -60,7 +61,7 @@ static void create_pack_file(void)
close(0);
close(fd[0]);
close(fd[1]);
- *p++ = "git-rev-list";
+ *p++ = "rev-list";
*p++ = "--objects";
if (create_full_pack || MAX_NEEDS <= nr_needs)
*p++ = "--all";
@@ -79,13 +80,13 @@ static void create_pack_file(void)
buf += 41;
}
*p++ = NULL;
- execvp("git-rev-list", argv);
+ execv_git_cmd(argv);
die("git-upload-pack: unable to exec git-rev-list");
}
dup2(fd[0], 0);
close(fd[0]);
close(fd[1]);
- execlp("git-pack-objects", "git-pack-objects", "--stdout", NULL);
+ exec_git_cmd("pack-objects", "--stdout");
die("git-upload-pack: unable to exec git-pack-objects");
}
^ permalink raw reply related
* Re: git pull on Linux/ACPI release tree
From: Adrian Bunk @ 2006-01-10 20:19 UTC (permalink / raw)
To: Linus Torvalds
Cc: Brown, Len, David S. Miller, linux-acpi, linux-kernel, akpm, git
In-Reply-To: <Pine.LNX.4.64.0601081909250.3169@g5.osdl.org>
On Sun, Jan 08, 2006 at 07:26:50PM -0800, Linus Torvalds wrote:
>...
> THIS is what "rebase" is for. It sounds like what you really want to do is
> not have a development branch at all, but you just want to track my tree
> and then keep track of a few branches of your own. In other words, you
> don't really have a "real" branch - you've got an odd collection of
> patches that you really want to carry around on top of _my_ branch. No?
Yes.
> Now, in this model, you're not really using git as a distributed system.
> In this model, you're using git to track somebody elses tree, and track a
> few patches on top of it, and then "git rebase" is a way to move the base
> that you're tracking your patches against forwards..
I am using the workaround of carrying the patches in a mail folder,
applying them in a batch, and not pulling from your tree between
applying a batch of patches and you pulling from my tree.
> It's also entirely possible that you may want to look at "stacked git"
> (stg), which is really more about a "quilt on top of git" approach. Which
> again, may or may not suit your needs better.
>...
After a quick look, stg seems to be an interesting project that might
suit my needs.
I'd say the main problem is that git with several other projects like
cogito and stg on top of it allow many different workflows. But finding
the one that suits one's needs without doing something in a wrong way
is non-trivial.
It might help if someone could write some kind of "Git for dummies" that
focusses only on the usage and advantages/disadvantages of user
interfaces like cogito, stg and (H)GCT and restricts the discussion of
git internals to a short paragraph in the introduction.
> Linus
cu
Adrian
--
"Is there not promise of rain?" Ling Tan asked suddenly out
of the darkness. There had been need of rain for many days.
"Only a promise," Lao Er said.
Pearl S. Buck - Dragon Seed
^ permalink raw reply
* Re: [PATCH 2/2] Remember and use GIT_EXEC_PATH on exec()'s
From: Alex Riesen @ 2006-01-10 20:15 UTC (permalink / raw)
To: Andreas Ericsson; +Cc: Michal Ostrowski, Junio C Hamano, git
In-Reply-To: <43C4075E.4070407@op5.se>
Andreas Ericsson, Tue, Jan 10, 2006 20:13:34 +0100:
> >My shell's rc-file doesn't get invoked when using ssh as a transport;
> >that's part of the problem.
>
> It does for me and everybody else. $HOME/.bashrc is read even for
> non-interactive shells. ...
Not really:
$ man bash
When bash is started non-interactively, to run a shell script, for
example, it looks for the variable BASH_ENV in the environment, expands
its value if it appears there, and uses the expanded value as the name
of a file to read and execute. Bash behaves as if the following com-
mand were executed:
if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi
but the value of the PATH variable is not used to search for the file
name.
$ ssh host2 strace -e open bash -c :
open("/etc/ld.so.cache", O_RDONLY) = 3
open("/lib/libncurses.so.5", O_RDONLY) = 3
open("/lib/tls/libdl.so.2", O_RDONLY) = 3
open("/lib/tls/libc.so.6", O_RDONLY) = 3
open("/dev/tty", O_RDWR|O_NONBLOCK|O_LARGEFILE) = -1 ENXIO (No such device or address)
open("/etc/mtab", O_RDONLY) = 3
open("/proc/meminfo", O_RDONLY) = 3
open("/proc/sys/kernel/ngroups_max", O_RDONLY) = 3
^ permalink raw reply
* Re: git pull on Linux/ACPI release tree
From: Linus Torvalds @ 2006-01-10 20:11 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Git Mailing List
In-Reply-To: <Pine.LNX.4.63.0601102010100.27199@wbgn013.biozentrum.uni-wuerzburg.de>
On Tue, 10 Jan 2006, Johannes Schindelin wrote:
>
> Those commits not reachable from the good commit are of no interest. Let's
> just ignore them.
Note that to avoid confusion, start talking about -multiple- good commits
early.
So we have a list of "known good islands" in the git-space. And yes, we
want to ignore anything that is reachable from them.
And here the magic part of"git-bisect.sh" is around line 133:
... --not $(cd "$GIT_DIR" && ls refs/bisect/good-*) ...
It tells git-rev-parse to generate a list of commits that we're _not_
interested in, and that list will be one of the most critical parts of the
stuff we give to "git-rev-list --bisect".
So that part of the script is literally the part that says "ignore all of
git space that is reachable from the good commits", because we've listed
all the good commits as refs named "refs/bisect/good-*".
> > You need to have a _set of points_ to separate the good from the bad. You
> > can think of it as a line that bisects the surface: if you were to print
> > out the development graph, the set of points literally _do_ form a virtual
> > line across the development surface.
>
> Okay, so there is a cut: Every directed path from good to bad has a single
> commit which is the first bad. Let's call the set of all such bad commits
> the cut set.
This set is uninteresting for two reasons:
- it's hard to calculate
- it's not the answer we want.
We want the _single_ commit that is the one that generates your "cut set".
Your "cut set" is really the "reachability border" from the single bad
commit we're interested in to all the possible development lines.
In practice, the "cut set" is just the "bad commit" plus all the merges
that merge that bad commit with somethign that wasn't reacable from it in
the first place.
So the "cut set" isn't interesting.
> git-bisect is not capable of identifying the cut set, but pretends that
> there really is only one bad commit (see bisect_bad()).
Not quite.
It could keep track of all bad commits (in fact, it does so in the log
file), but the fact is, none but the lastest bad commit we have found
matters.
By definition, "git bisect" is always going to test a commit that is
reachable from the previously known bad commit. Agreed? Anything else
would be insane - we know that we had a bad stat, and we're interested in
finding out how _that_ bad state happened, so we're only ever interested
in commits that are ancestors to that bad state.
So our search-space is _literally_ defined by two things:
- the surface of "known good" commits (which defines the commits that
aren't interesting).
This is the "--not refs/bisect/good-*" part
- the last "known bad" commit.
We'll always search the git commit space defined by these two knowns,
agreed?
Now, realize that if we find a new bad commit, since that bad commit was
by definition reachable from the _old_ bad commit (since we didn't even
search outside its reachability), then equally by definition the
reachability from that new bad commit is a strict superset of the
reachability of the old bad commit.
So when we find a new bad commit, the old bad commit is no longer
interesting.
So when you say "pretends that there really is only one bad commit", you
didn't realize that it's not about "pretending". It's very fundamental:
there is only ever _one_ bad commit that is interesting. It's the last one
we found.
Even if we started out with two bad commits (ie some person reported two
different versions as being bad), we're _still_ not interested in using
them both. We should pick one of them, because the reachability area
defined by two bad commits is always a superset of the reachability of
either one.
So having multiple bad commits is _never_ interesting.
> But I see two problems with that:
>
> - a problem can be introduced independently in two different branches, and
> occur in both of them before the merge (in which case bisect only
> catches one of the commits), and
This is fine. Depending on whatever random factors, we'll test one of them
first, and eventually find _one_ of the commits that fix it. If the exact
same bug was introduced somewhere else, and merged, then undoing just the
"one" bug will obviously undo the other one too.
If a _different_ bug was introduced (even if it had the same effects),
yes, you now have two separate bugs. And bisecting two bugs is hard. You
need to separate them out some way.
> - AFAICT if the cut set is one merge and one regular commit, bisect could
> identify the merge by error.
It will never identify a commit without having done a full bisection, so
if it ever had the choice of a "merge" and the "commit leading up to the
merge", it will always have tried the "commit leading up to the merge",
and decided that it was fundamentally more recent (had "smaller
reachability") that the merge, and pinpoint it.
> BTW I think there is a thinko in git-rev-list.txt:
>
> > Thus, if 'git-rev-list --bisect foo ^bar ^baz' outputs 'midpoint', the
> > output of 'git-rev-list foo ^midpoint' and 'git-rev-list midpoint ^bar
> ^ this should be
> 'git-rev-list foo ^midpoint ^bar ^baz'
> > ^baz' would be of roughly the same length
Yes.
Linus
^ permalink raw reply
* Re: [PATCH 2/2] Remember and use GIT_EXEC_PATH on exec()'s
From: Johannes Schindelin @ 2006-01-10 19:55 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Michal Ostrowski, Andreas Ericsson, git
In-Reply-To: <7vzmm36f1x.fsf@assigned-by-dhcp.cox.net>
Hi,
On Tue, 10 Jan 2006, Junio C Hamano wrote:
> Michal Ostrowski <mostrows@watson.ibm.com> writes:
>
> > git programs exec other git programs, but they also exec non-git
> > programs. I think it is not appropriate to change PATH (via
> > prepend_to_path) because this may result in unexpected behavior when
> > exec'ing non-git programs:
>
> This is a valid concern.
Why? If what is prepended to PATH only contains git programs?
Ciao,
Dscho
^ permalink raw reply
* Re: [PATCH 2/2] Remember and use GIT_EXEC_PATH on exec()'s
From: Junio C Hamano @ 2006-01-10 19:47 UTC (permalink / raw)
To: Michal Ostrowski; +Cc: Andreas Ericsson, git
In-Reply-To: <1136910406.11717.579.camel@brick.watson.ibm.com>
Michal Ostrowski <mostrows@watson.ibm.com> writes:
> One could make all the scripts depend on GIT_EXEC_PATH instead of PATH.
> At build time one could generate wrapper functions in git-sh-setup:
>
> function git-foo () {
> $(GIT_EXEC_PATH)/git-foo $*;
> }
>
> Presuming that all scripts include git-sh-setup, no other shell script
> changes would be needed.
Is "git-foo" a valid name to define shell function as?
> My shell's rc-file doesn't get invoked when using ssh as a transport;
> that's part of the problem.
Not any rc, or are you bitten by bash/ssh misfeature that
noninteractive sessions do not start with .bash_profile?
>> > Once you have that implemented, we can have a separate discussion of how
>> > the executable is to be found;
>> > - should we use PATH?
>> > - should we change PATH?
>> > - should we always exec using an absolute file name? (my preference)
The goal here is to make sure we exec the program from the same
release (unless user overrides it with GIT_EXEC_PATH to say "I
want to try 0.99.9k, not the latest one"), but how? The last
one feels the most correct way if done right.
> git programs exec other git programs, but they also exec non-git
> programs. I think it is not appropriate to change PATH (via
> prepend_to_path) because this may result in unexpected behavior when
> exec'ing non-git programs:
This is a valid concern.
^ permalink raw reply
* Re: git-bisect is magical
From: Linus Torvalds @ 2006-01-10 19:45 UTC (permalink / raw)
To: walt; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0601101131540.4939@g5.osdl.org>
On Tue, 10 Jan 2006, Linus Torvalds wrote:
>
> You can _undo_ the revert, so it's not permanent in that sense. Just do
>
> git reset --hard origin
>
> and your "master" branch will be forced back to the state that "origin"
> was in.
Btw, you can try this (careful - it will also undo any dirty state you
have in your working tree), and then do the "pull" again (which should now
be a trivial fast-forward) and then just try to do the "git revert" on the
new state.
An even better option is obviously to figure out _why_ that commit broke
for you in the first place, and get it fixed up-stream, so that you don't
even need to revert it any more, and the "pull" just fixes it for you ;)
Linus
^ permalink raw reply
* Re: git-bisect is magical
From: Linus Torvalds @ 2006-01-10 19:42 UTC (permalink / raw)
To: walt; +Cc: git
In-Reply-To: <dq11c6$g15$1@sea.gmane.org>
On Tue, 10 Jan 2006, walt wrote:
>
> Yesterday (while reading the bisect HOWTO) I did a git-revert on the
> 'bad' commit, which indeed fixed my bug. But this caused a problem
> this morning when I did my daily 'cg-update' for the kernel.
>
> I got a merge conflict (of course) because of yesterday's git-revert.
Well, it's not "of course". It might have merged fine, and to some degree
you were just unlukcy that it created a conflict with new development),
but yes, it will now always be a _merge_ rather than a fast-forward, as
your tree was now different from my historical tree.
> My question (I think) is: exactly what did I change when I did the
> git-revert?
You can think of a "git revert" as being just a "apply the reverse of that
one diff, and commit it". So a "git revert" really just add a _new_
commit, it never _removes_ anything.
(That's fundamental: in a distributed system you can't undo history).
Now, strictly speaking "git revert" actually does something much smarter
than just apply the diff in reverse - which means that it works better if
other things have changed in that area - but if you think of it as the
"commit the diff in reverse" case, you'll be thinking the right way.
> I notice in retrospect that (in refs/heads) master is
> no longer identical to origin. I think (but I'm not certain) that
> the two used to be the same. (For example, in my 'git' repository
> the 'master' and 'origin' files are identical.)
Exactly.
Do a "git-whatchanged -p", and you'll see what your "git revert" did.
> Did the git-revert change my local kernel repository permanently?
Yes.
You can _undo_ the revert, so it's not permanent in that sense. Just do
git reset --hard origin
and your "master" branch will be forced back to the state that "origin"
was in.
> Did the merge-conflict prevent today's cg-update from updating my
> local repository with your commits from the last 24 hours? Or is
> the merge conflict only with my currently checked-out-and-modified
> copy of the repository?
I'm not sure. It could be either, you don't tell what the conflict message
is.
If the conflict message is
Entry 'xyzzy' not uptodate. Cannot merge.
that means that no merge was even tried, because you had dirty contents in
your tree, and the merge simply won't touch it. You need to commit the
dirty state and let the merge try to auto-merge it, or you need to undo
it so that your tree is clean.
If the conflict message is something like
CONFLICT (content): merge conflict in xyzzy
that means that the merge _was_ done, but there was a content conflict
that you need to fix up by hand and finish the merge.
> Is it clear to you why I'm confused? :o) Most of my muddle is
> because I don't know the definitions of some important words, I
> suspect.
Hey, keep the questions coming. And if something starts making sense, I
suspect that Junio would be very happy with additions to the Documentation
subdirectory to try to help others... Hint, hint.
Linus
^ permalink raw reply
* Re: git pull on Linux/ACPI release tree
From: Johannes Schindelin @ 2006-01-10 19:38 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0601101048440.4939@g5.osdl.org>
Hi,
[cut down the Cc: list, since this is getting special]
On Tue, 10 Jan 2006, Linus Torvalds wrote:
> > If you bisect, you test a commit. If the commit is bad, you assume *all*
> > commits before that as bad. If it is good, you assume *all* commits after
> > that as good.
>
> No, that's not how bisect works at all.
Okay, so I got that wrong. But for a good reason: this is not the meaning
of bisection in my lectures. Doesn't matter.
> It's true that if a commit is bad, then all the commits _reachable_ from
> that commit are considered bad.
>
> And it's true that if a commit is good, then all commits that _reach_ that
> commit are considered good.
>
> But that doesn't mean that there is an ordering. The commits that fall
> into the camp of being "neither good nor bad" are _not_ ordered. There are
> commits in there that are not directly reachable from the good commit.
Those commits not reachable from the good commit are of no interest. Let's
just ignore them.
> > Now, if you have a 2-dimensional surface, you don't have a *point*, but
> > typically a *line* separating good from bad.
>
> Exactly.
>
> And a git graph is not really a two-dimensional surface, but exactly was
> with a 2-dimensional surface, it is _not_ enough to have a *point* to
> separate the good from bad.
>
> You need to have a _set of points_ to separate the good from the bad. You
> can think of it as a line that bisects the surface: if you were to print
> out the development graph, the set of points literally _do_ form a virtual
> line across the development surface.
Okay, so there is a cut: Every directed path from good to bad has a single
commit which is the first bad. Let's call the set of all such bad commits
the cut set.
Is git-bisect capable of identifying all of the cut set, or just a single
one?
> > Further, the comparison with 2 dimensions is particularly bad.
>
> No it is not. It's a very good comparison.
>From your explanation I understand now why you like that comparison.
> > So, how is bisect supposed to work if you don't have one straight
> > development line from bad to good?
>
> Read the code.
>
> I'm pretty proud of it.
I bet nobody can tell ;-)
Well, I read the code. And I answer my own question from 18--19 lines ago:
git-bisect is not capable of identifying the cut set, but pretends that
there really is only one bad commit (see bisect_bad()).
That may be the best choice if all commits in the cut set except one are
merges. (It is the best if the cut set contains only one element.)
But I see two problems with that:
- a problem can be introduced independently in two different branches, and
occur in both of them before the merge (in which case bisect only
catches one of the commits), and
- AFAICT if the cut set is one merge and one regular commit, bisect could
identify the merge by error.
Of course, all this makes only a difference if the bisect has to cross a
merge.
BTW I think there is a thinko in git-rev-list.txt:
> Thus, if 'git-rev-list --bisect foo ^bar ^baz' outputs 'midpoint', the
> output of 'git-rev-list foo ^midpoint' and 'git-rev-list midpoint ^bar
^ this should be
'git-rev-list foo ^midpoint ^bar ^baz'
> ^baz' would be of roughly the same length
Ciao,
Dscho
^ permalink raw reply
* Re: git pull on Linux/ACPI release tree
From: Linus Torvalds @ 2006-01-10 19:28 UTC (permalink / raw)
To: Johannes Schindelin
Cc: Kyle Moffett, Martin Langhoff, Luben Tuikov, Brown, Len,
Luck, Tony, Junio C Hamano, David S. Miller, linux-acpi,
LKML Kernel, Andrew Morton, Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0601101048440.4939@g5.osdl.org>
On Tue, 10 Jan 2006, Linus Torvalds wrote:
>
> Now, the git history is _not_ really a two-dimensional surface, so it's
> just an analogy, not an exact identity. But from a visualization
> standpoint, it's a good way to think of each "git bisect" as adding a
> _line_ on the surface rather than a point on a linear line.
Actually, the way I think of it is akin to the "light cones" in physics. A
point in space-time doesn't define a fully ordered "before and after": but
it _does_ describe a "light cone" which tells you what is reachable from
that point, and what that point reaches. Within those cones, that
particular point ("commit") has a strict ordering.
And exactly as in physics, in git there's a lot of space that is _not_
ordered by that commit. And the way to bisect is basically to find the
right points in "git space" to create the right "light cone" that you
find the point where the git space that is reachable from that commit has
the same volume as the git space that isn't reachable.
And maybe that makes more sense to you (if you're into physics), or maybe
it makes less sense to you.
Now, since we always search the "git space" in the cone that is defined by
"reachable from the bad commit, but not reachable from any good commit",
the way we handle "bad" and "good" is actually not a mirror-image. If we
fine a new _bad_ commit, we know that it was reachable from the old bad
commit, and thus the old bad commit is now uninteresting: the new bad
commit forms a "past light cone" that is a strict subset of the old one,
so we can totally discard the old bad commit from any future
consideration. It doesn't tell us anything new.
In contrast, if we find a new _good_ commit, the "past light cone" (aka
"set of commits reachable from it") is -not- necessarily a proper superset
of the previous set of good commits, so when we find a good commit, we
still need to carry the _other_ good commits around, and the "known good"
universe is the _union_ of all the "good commit past lightcones".
Then the "unknown space" is the set difference of the "past lightcone of
the bad commit" and of this "union of past lightcones of good commits".
It's the space that is reachable from the known-bad commit, but not
reachable from any known-good commit.
So this means that when doing bisection, what we want to do is find the
point in git space that has _new_ "reachability" within that unknown space
that is as close to half that volume as space as possible. And that's
exactly what "git-rev-list --bisect" calculates.
So every time, we try to either move the "known bad" light-cone down in
time in the unknown space, _or_ we add a new "known good" light-cone. In
either case, the "unknown git space" keeps shrinking by half each time.
("by half" is not exact, because git space is not only quanticized, it
also has a rather strange "distance function". In other words, we're
talking about a rather strange space. The good news is that the space is
small enough that we can just enumerate every quantum and simply
calculate the volume it defines in that space. IOW, we do a very
brute-force thing, and it works fine).
Linus
^ permalink raw reply
* Re: git-bisect is magical
From: walt @ 2006-01-10 19:19 UTC (permalink / raw)
To: git
In-Reply-To: <Pine.LNX.4.64.0601091516460.5588@g5.osdl.org>
Linus Torvalds wrote:
[...]
> but the fact is, whenever you leave off the version specifier, it will
> just assume that "current HEAD" is it...
I'm still very much struggling with nomenclature, and trying to
deduce what is a synonym for what, and which words cannot be used
synonymously.
Yesterday (while reading the bisect HOWTO) I did a git-revert on the
'bad' commit, which indeed fixed my bug. But this caused a problem
this morning when I did my daily 'cg-update' for the kernel.
I got a merge conflict (of course) because of yesterday's git-revert.
My question (I think) is: exactly what did I change when I did the
git-revert? I notice in retrospect that (in refs/heads) master is
no longer identical to origin. I think (but I'm not certain) that
the two used to be the same. (For example, in my 'git' repository
the 'master' and 'origin' files are identical.)
Did the git-revert change my local kernel repository permanently?
Did the merge-conflict prevent today's cg-update from updating my
local repository with your commits from the last 24 hours? Or is
the merge conflict only with my currently checked-out-and-modified
copy of the repository?
Is it clear to you why I'm confused? :o) Most of my muddle is
because I don't know the definitions of some important words, I
suspect.
Thanks!
^ permalink raw reply
* Re: [PATCH 2/2] Remember and use GIT_EXEC_PATH on exec()'s
From: Andreas Ericsson @ 2006-01-10 19:13 UTC (permalink / raw)
To: Michal Ostrowski; +Cc: Junio C Hamano, git
In-Reply-To: <1136910406.11717.579.camel@brick.watson.ibm.com>
Michal Ostrowski wrote:
> On Tue, 2006-01-10 at 16:01 +0100, Andreas Ericsson wrote:
>
>
>>This is the case in the git potty already. git.c must prepend
>>--exec-path to $PATH, or the whole idea of being able to move scripts
>>out of the $PATH fails (at least it fails without changing quite a few
>>of the scripts).
>
>
> One could make all the scripts depend on GIT_EXEC_PATH instead of PATH.
> At build time one could generate wrapper functions in git-sh-setup:
>
> function git-foo () {
> $(GIT_EXEC_PATH)/git-foo $*;
> }
>
> Presuming that all scripts include git-sh-setup, no other shell script
> changes would be needed.
>
Yuck, for two reasons.
* Not all scripts include git-sh-setup, and for good reasons. If this is
what you intend please make sure you don't break anything in the process.
* This will spawn a sub-shell for each git-foo process called. Shells
are way more expensive than the git potty, so the performance hit in
iterations might be considerable. Think StGit and Cogito as well.
On a side-note, $* will break quoting (you should use "$@" instead, with
double-quotes attached), and
$(GIT_EXEC_PATH)/git-foo $*
will try to execute GIT_EXEC_PATH and prepend its output to the rest of
the command, which is quite obviously wrong.
>
>>Since it's already in place in the potty and that's required to be in
>>the $PATH, I think Junio's suggestion of running execlp("git", "git",
>>...) is a good one. It will add one extra fork() and execve() for each
>>clone/pull/push, but that isn't much of an issue, really.
>>
>
>
> The patch I posted most recently does something comparable; all exec's
> by C git programs go through exec_git_cmd, which actually implements the
> "git potty" logic (and git.c itself uses exec_git_cmd). If there is to
> be a consistent rule for how to exec a git program from a git C program,
> I think that it's reasonable that there be an API to enforce it.
>
True. Perhaps I misread your patch or your reasoning.
> Note that the creation and use of such a function simply means that we
> hide the logic that handles PATH/GIT_EXEC_PATH; how git_exec_cmd()
> actually calls execve() and how PATH and GIT_EXEC_PATH are used is a
> separate issue. When it comes to the former, I think it is best to have
> all exec's of git programs go through an interface that imposes the same
> PATH/GIT_EXEC_PATH logics. As to the latter, my only concern is that we
> should never do 'setenv("PATH",....)'.
>
setenv("PATH", ..) is way preferrable over the git-setup.sh hackery
suggested above, so long as it's only ever done in the git potty. That's
what the potty is there for, after all.
>
>>>An approach that I think is better is to require all exec's of git
>>>programs from within git programs to use a specific git interface,
>>>rather than letting each one set up it's own exec parameters.
>>>
>>
>>A better idea would be to teach {send,upload}-pack about $GIT_EXEX_PATH
>>and export it from your shells rc-file.
>>
>
>
> My shell's rc-file doesn't get invoked when using ssh as a transport;
> that's part of the problem.
>
It does for me and everybody else. $HOME/.bashrc is read even for
non-interactive shells. $HOME/.bash_profile isn't. If you're using
git-shell you're in to a whole different situation, but you didn't say
so so I don't think you are.
>>
>>If a user invokes "/home/user/bin/git-foo" rather than
>>"/home/user/bin/git foo" he/she will have to have the rest of the
>>git-suite in the $PATH. Prepending whatever directory any git-* program
>>happens to reside in to $PATH is not a good idea.
>
>
> Isn't this exactly what git.c is doing currently via prepend_to_path()?
>
No. git prepends whatever was passed in --exec-path=/some/path, what's
found in $GIT_EXEC_PATH or the GIT_EXEC_PATH pre-processor macro set at
compile-time, in that order of preference. There's a very big difference.
> git programs exec other git programs, but they also exec non-git
> programs. I think it is not appropriate to change PATH (via
> prepend_to_path) because this may result in unexpected behavior when
> exec'ing non-git programs:
>
> Suppose git is installed in /usr/bin, where a "diff" resided.
> I've got my own version of "diff" in /home/user/bin.
> PATH=/home/user/bin:/usr/bin.
>
> If git now tries to execute "diff", after having run
> prepend_to_path(), /usr/bin/diff gets executed, not /home/user/bin/diff.
> The user has set up PATH to ensure that /home/user/bin/diff is the diff,
> but by mucking with PATH we subvert their intentions.
>
Good point. Perhaps we should only prepend to path when the directory
isn't already in $PATH, or append rather than prepend.
--
Andreas Ericsson andreas.ericsson@op5.se
OP5 AB www.op5.se
Tel: +46 8-230225 Fax: +46 8-230231
^ permalink raw reply
* Re: git pull on Linux/ACPI release tree
From: Linus Torvalds @ 2006-01-10 19:01 UTC (permalink / raw)
To: Johannes Schindelin
Cc: Kyle Moffett, Martin Langhoff, Luben Tuikov, Brown, Len,
Luck, Tony, Junio C Hamano, David S. Miller, linux-acpi,
LKML Kernel, Andrew Morton, Git Mailing List
In-Reply-To: <Pine.LNX.4.63.0601101938420.26999@wbgn013.biozentrum.uni-wuerzburg.de>
On Tue, 10 Jan 2006, Johannes Schindelin wrote:
> >
> > Think of it as doing a binary search in a 2-dimensional surface - you
> > can't linearize the plane, but you can decide to test first one half of
> > the surface, and then depending on whether it was there, you can halve
> > that surface etc..
>
> How?
>
> If you bisect, you test a commit. If the commit is bad, you assume *all*
> commits before that as bad. If it is good, you assume *all* commits after
> that as good.
No, that's not how bisect works at all.
It's true that if a commit is bad, then all the commits _reachable_ from
that commit are considered bad.
And it's true that if a commit is good, then all commits that _reach_ that
commit are considered good.
But that doesn't mean that there is an ordering. The commits that fall
into the camp of being "neither good nor bad" are _not_ ordered. There are
commits in there that are not directly reachable from the good commit.
> Now, if you have a 2-dimensional surface, you don't have a *point*, but
> typically a *line* separating good from bad.
Exactly.
And a git graph is not really a two-dimensional surface, but exactly was
with a 2-dimensional surface, it is _not_ enough to have a *point* to
separate the good from bad.
You need to have a _set of points_ to separate the good from the bad. You
can think of it as a line that bisects the surface: if you were to print
out the development graph, the set of points literally _do_ form a virtual
line across the development surface.
(Actually, you can't in general print out the development graph on a
2-dimensional paper without having development lines that cross each
other, but you could actually do it in three dimensions, where the
"boundary" between good and bad is actually a 2-dimensional surface in
3-dimensional space).
But to describe the surface of "known good", you actually just need a list
of known good commits, and the "commits reachable from those commits"
_becomes_ the surface.
> Further, the comparison with 2 dimensions is particularly bad.
No it is not. It's a very good comparison.
In a linearized model (one-dimensional, fully ordered set), the only thing
you need for bisection is two points: the beginning and the end.
In the git model, you need _many_ points to describe the area being
bisected. Exactly the same way as if you were to bisect a 2-dimensional
surface.
Now, the git history is _not_ really a two-dimensional surface, so it's
just an analogy, not an exact identity. But from a visualization
standpoint, it's a good way to think of each "git bisect" as adding a
_line_ on the surface rather than a point on a linear line.
> So, how is bisect supposed to work if you don't have one straight
> development line from bad to good?
Read the code.
I'm pretty proud of it. It's simple, and it's obvious once you think about
it, but it is pretty novel as far as I know. BK certainly had nothing
similar, not have I heard of anythign else that does it. Git _might_ be
the first thing that has ever done it, although it's simple enough that I
wouldn't be surprised if others have too.
Linus
^ permalink raw reply
* Re: killing a branch
From: Jens Axboe @ 2006-01-10 18:59 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.64.0601100910530.4939@g5.osdl.org>
On Tue, Jan 10 2006, Linus Torvalds wrote:
>
>
> On Tue, 10 Jan 2006, Jens Axboe wrote:
> >
> > Alright, I'll just have to shake the habit of running git prune to rid
> > myself of that dirty dirty feeling.
>
> Yeah, I'm slowly shaking it off too. I used to run git-fsck-objects
> religiously just because I worried about bugs. I still do it, but
> especially with the recursive-strategy merging, I get "dangling blob"
> messages every once in a while that are _not_ due to bugs, but just due to
> the temporary merge object.
>
> So I'm learning to ignore them, and prune the tree only occasionally,
> instead of compulsively every time.
Compulsive is the right word, it just itches to run the prune after
killing a branch... I'll try and learn as well.
--
Jens Axboe
^ permalink raw reply
* Re: git pull on Linux/ACPI release tree
From: Johannes Schindelin @ 2006-01-10 18:45 UTC (permalink / raw)
To: Linus Torvalds
Cc: Kyle Moffett, Martin Langhoff, Luben Tuikov, Brown, Len,
Luck, Tony, Junio C Hamano, David S. Miller,
linux-acpi-u79uwXL29TY76Z2rM5mHXA, LKML Kernel, Andrew Morton,
Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0601101015260.4939-hNm40g4Ew95AfugRpC6u6w@public.gmane.org>
Hi,
On Tue, 10 Jan 2006, Linus Torvalds wrote:
>
> On Tue, 10 Jan 2006, Kyle Moffett wrote:
> >
> > On Jan 10, 2006, at 01:38, Martin Langhoff wrote:
> > >
> > > The more complex your tree structure is, the more the interactions are
> > > likely to be part of the problem. Is git-bisect not useful in this scenario?
> >
> > IIRC git-bisect just does an outright linearization of the whole tree anyways,
> > which makes git-bisect work everywhere, even in the presence of difficult
> > cross-merges.
>
> It's not really a linearization - at no time does git-bisect _order_ the
> commits. After all, no linear order actually exists.
>
> Instead, it really cuts the tree up into successively smaller parts.
>
> Think of it as doing a binary search in a 2-dimensional surface - you
> can't linearize the plane, but you can decide to test first one half of
> the surface, and then depending on whether it was there, you can halve
> that surface etc..
How?
If you bisect, you test a commit. If the commit is bad, you assume *all*
commits before that as bad. If it is good, you assume *all* commits after
that as good.
Now, if you have a 2-dimensional surface, you don't have a *point*, but
typically a *line* separating good from bad.
Further, the comparison with 2 dimensions is particularly bad. You
*have* partially linear development lines, it got *nothing* to do with
an area. The commits still make up a *list*, and it depends how you
*order* that list for bisect. (And don't tell me they are not ordered:
they are.)
If you order the commits by date, you don't get anything meaningful point
before which it is bad, and after which it is good.
So, how is bisect supposed to work if you don't have one straight
development line from bad to good?
Ciao,
Dscho
-
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: git pull on Linux/ACPI release tree
From: Linus Torvalds @ 2006-01-10 18:27 UTC (permalink / raw)
To: Kyle Moffett
Cc: Martin Langhoff, Luben Tuikov, Brown, Len, Luck, Tony,
Junio C Hamano, David S. Miller, linux-acpi, LKML Kernel,
Andrew Morton, Git Mailing List
In-Reply-To: <252A408D-0B42-49F3-92BC-B80F94F19F40@mac.com>
On Tue, 10 Jan 2006, Kyle Moffett wrote:
>
> On Jan 10, 2006, at 01:38, Martin Langhoff wrote:
> >
> > The more complex your tree structure is, the more the interactions are
> > likely to be part of the problem. Is git-bisect not useful in this scenario?
>
> IIRC git-bisect just does an outright linearization of the whole tree anyways,
> which makes git-bisect work everywhere, even in the presence of difficult
> cross-merges.
It's not really a linearization - at no time does git-bisect _order_ the
commits. After all, no linear order actually exists.
Instead, it really cuts the tree up into successively smaller parts.
Think of it as doing a binary search in a 2-dimensional surface - you
can't linearize the plane, but you can decide to test first one half of
the surface, and then depending on whether it was there, you can halve
that surface etc..
> On the other hand, if you are git-bisecting ACPI changes
> (perhaps due to some ACPI breakage), and ACPI has 10 pulls from mainline, you
> _also_ have to wade through the bisection of any other changes that occurred
> in mainline, even if they're totally irrelevant.
Yes. Although if you _know_ that the problem happened in a specific file
or specific subdirectory, you can actually tell "git bisect" to only
bother with changes to that file/directory/set-of-directories to speed up
the search.
IOW, if you absolutely know that it's ACPI-related, you can do something
like
git bisect start drivers/acpi arch/i386/kernel/acpi
to tell the bisect code that it should totally ignore anything that
doesn't touch those two directories.
However, if it turns out that you were wrong (and the ACPI breakage was
brought on by something that changed something else), "git bisect" will
just get confused and report the wrong commit, so this is really something
you should be careful with (and verify the end result by checking that
undoing that _particular_ commit really fixes things).
And yes, "git bisect" _will_ work with bugs that depend on two branches of
a merge: it will point to the merge commit itself as being the problem.
Now, at that point you really are screwed, and you'll have to figure out
why both branches work, but the combination of them do not.
Maybe it's as simple as just a merge done wrong (bad manual fixups), but
maybe it's a perfectly executed merge that just happens to have one branch
changing the assumptions that the other branch depended on.
Happily, that is not very common. I know people are using "git bisect",
and I don't think anybody has ever reported it so far. It will happen
eventually, but I'd actually expect it to be much more common that "git
bisect" will hit other - worse - problems, like bugs that "come and go",
and that a simple bisection simply cannot find because they aren't
totally repeatable.
Linus
^ permalink raw reply
* Re: git pull on Linux/ACPI release tree
From: Kyle Moffett @ 2006-01-10 18:05 UTC (permalink / raw)
To: Martin Langhoff
Cc: Luben Tuikov, Brown, Len, Luck, Tony, Junio C Hamano,
Linus Torvalds, David S. Miller, linux-acpi, LKML Kernel,
Andrew Morton, Git Mailing List
In-Reply-To: <46a038f90601092238r3476556apf948bfe5247da484@mail.gmail.com>
On Jan 10, 2006, at 01:38, Martin Langhoff wrote:
> On 1/10/06, Kyle Moffett <mrmacman_g4@mac.com> wrote:
>> If they all work, then we know precisely that it's the
>> interactions between them, which also makes debugging a lot easier.
>
> The more complex your tree structure is, the more the interactions
> are likely to be part of the problem. Is git-bisect not useful in
> this scenario?
IIRC git-bisect just does an outright linearization of the whole tree
anyways, which makes git-bisect work everywhere, even in the presence
of difficult cross-merges. On the other hand, if you are git-
bisecting ACPI changes (perhaps due to some ACPI breakage), and ACPI
has 10 pulls from mainline, you _also_ have to wade through the
bisection of any other changes that occurred in mainline, even if
they're totally irrelevant. This is why it's useful to only pull
mainline into your tree (EX: ACPI) when you functionally depend on
changes there (as Linus so eloquently expounded upon).
Cheers,
Kyle Moffett
--
Q: Why do programmers confuse Halloween and Christmas?
A: Because OCT 31 == DEC 25.
^ permalink raw reply
* Re: undoing changes with git-checkout -f
From: Alex Riesen @ 2006-01-10 17:32 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: git
In-Reply-To: <Pine.LNX.4.63.0601101743180.26542@wbgn013.biozentrum.uni-wuerzburg.de>
On 1/10/06, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> > > > Can we teach the git:// fetch program to use CONNECT over HTTP
> > > > proxies? rsync can do this, but git:// cannot, so firewalls that block
> > > > 9418 mean we use rsync://
> > >
> > > I think it is good and well with the proxy command support. Everybody can
> > > write a little script.
> > >
> > > Otherwise, where would it end? If you include http_proxy functionality in
> > > git, why not also https_proxy functionality? And if that, why not
> >
> > And, BTW, why not? It may as well stop here.
>
> Because it's not the purpose of git. It is the purpose of a tunnel. Let's
> not make the mistake of Microsoft here: integrate everything until
> everything breaks.
Of course, I do not propose to put the code into connect.c! Let it be
ip-tunnel.pl,
or something like that (which btw is really awkward to handle under a well-known
disabled OS).
But, it is not exactly standard tunnel, is it? I mean, can you use it
for something
else? If not, is there really a point _not_ to put it in the git
repository? As tunnel
script or program, or as an instruction file on how to setup a firewall?
^ permalink raw reply
* [PATCH] stgit: typo fixes
From: Pavel Roskin @ 2006-01-10 17:14 UTC (permalink / raw)
To: Catalin Marinas; +Cc: git
Signed-off-by: Pavel Roskin <proski@gnu.org>
diff --git a/gitmergeonefile.py b/gitmergeonefile.py
index 9344d33..2f327a3 100755
--- a/gitmergeonefile.py
+++ b/gitmergeonefile.py
@@ -121,7 +121,7 @@ def __conflict():
# $2 - file in branch1 SHA1 (or empty)
# $3 - file in branch2 SHA1 (or empty)
# $4 - pathname in repository
-# $5 - orignal file mode (or empty)
+# $5 - original file mode (or empty)
# $6 - file in branch1 mode (or empty)
# $7 - file in branch2 mode (or empty)
#
@@ -140,7 +140,7 @@ __checkout_files()
if orig_hash:
# modified in both
if file1_hash and file2_hash:
- # if modes are the same (git-read-tree probably dealed with it)
+ # if modes are the same (git-read-tree probably dealt with it)
if file1_hash == file2_hash:
if os.system('git-update-index --cacheinfo %s %s %s'
% (file1_mode, file1_hash, path)) != 0:
@@ -242,8 +242,8 @@ else:
__remove_files()
sys.exit(os.system('git-checkout-index -u -f -- %s' % path))
-# Un-handled case
-print >> sys.stderr, 'Error: Un-handled merge conflict'
+# Unhandled case
+print >> sys.stderr, 'Error: Unhandled merge conflict'
print >> sys.stderr, 'gitmergeonefile.py "%s" "%s" "%s" "%s" "%s" "%s" "%s"' \
% tuple(sys.argv[1:8])
__conflict()
diff --git a/stgit/commands/common.py b/stgit/commands/common.py
index 8084cbd..88f1433 100644
--- a/stgit/commands/common.py
+++ b/stgit/commands/common.py
@@ -1,4 +1,4 @@
-"""Function/variables commmon to all the commands
+"""Function/variables common to all the commands
"""
__copyright__ = """
@@ -92,7 +92,7 @@ def check_head_top_equal():
if not crt_series.head_top_equal():
raise CmdException, \
'HEAD and top are not the same. You probably committed\n' \
- ' changes to the tree ouside of StGIT. If you know what you\n' \
+ ' changes to the tree outside of StGIT. If you know what you\n' \
' are doing, use the "refresh -f" command'
def check_conflicts():
diff --git a/stgit/commands/imprt.py b/stgit/commands/imprt.py
index 6ccdcc9..87fd5da 100644
--- a/stgit/commands/imprt.py
+++ b/stgit/commands/imprt.py
@@ -28,7 +28,7 @@ usage = """%prog [options] [<file>]
Create a new patch and apply the given GNU diff file (or the standard
input). By default, the file name is used as the patch name but this
-can be overriden with the '--name' option. The patch can either be a
+can be overridden with the '--name' option. The patch can either be a
normal file with the description at the top or it can have standard
mail format, the Subject, From and Date headers being used for
generating the patch information.
@@ -219,7 +219,7 @@ def func(parser, options, args):
elif filename:
patch = os.path.basename(filename)
else:
- raise CmdException, 'Unkown patch name'
+ raise CmdException, 'Unknown patch name'
# the defaults
message = author_name = author_email = author_date = committer_name = \
diff --git a/stgit/commands/pick.py b/stgit/commands/pick.py
index c01c799..e932cf0 100644
--- a/stgit/commands/pick.py
+++ b/stgit/commands/pick.py
@@ -28,7 +28,7 @@ usage = """%prog [options] [<patch@branc
Import a patch from a different branch or a commit object into the
current series. By default, the name of the imported patch is used as
-the name of the current patch. It can be overriden with the '--name'
+the name of the current patch. It can be overridden with the '--name'
option. A commit object can be reverted with the '--reverse'
option. The log and author information are those of the commit object."""
diff --git a/stgit/git.py b/stgit/git.py
index a7b1c3f..61436bb 100644
--- a/stgit/git.py
+++ b/stgit/git.py
@@ -274,7 +274,7 @@ def rev_parse(git_id):
raise GitException, 'Unknown revision: %s' % git_id
def branch_exists(branch):
- """Existance check for the named branch
+ """Existence check for the named branch
"""
for line in _output_lines(['git-rev-parse', '--symbolic', '--all']):
if line.strip() == branch:
--
Regards,
Pavel Roskin
^ permalink raw reply related
* Re: killing a branch
From: Linus Torvalds @ 2006-01-10 17:12 UTC (permalink / raw)
To: Jens Axboe; +Cc: Junio C Hamano, git
In-Reply-To: <20060110112608.GU3389@suse.de>
On Tue, 10 Jan 2006, Jens Axboe wrote:
>
> Alright, I'll just have to shake the habit of running git prune to rid
> myself of that dirty dirty feeling.
Yeah, I'm slowly shaking it off too. I used to run git-fsck-objects
religiously just because I worried about bugs. I still do it, but
especially with the recursive-strategy merging, I get "dangling blob"
messages every once in a while that are _not_ due to bugs, but just due to
the temporary merge object.
So I'm learning to ignore them, and prune the tree only occasionally,
instead of compulsively every time.
Linus
^ permalink raw reply
* Re: undoing changes with git-checkout -f
From: Johannes Schindelin @ 2006-01-10 16:45 UTC (permalink / raw)
To: Alex Riesen; +Cc: git
In-Reply-To: <81b0412b0601100817h2a288a4ag337c749857f2c7fc@mail.gmail.com>
Hi,
On Tue, 10 Jan 2006, Alex Riesen wrote:
> On 1/10/06, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> > > Can we teach the git:// fetch program to use CONNECT over HTTP
> > > proxies? rsync can do this, but git:// cannot, so firewalls that block
> > > 9418 mean we use rsync://
> >
> > I think it is good and well with the proxy command support. Everybody can
> > write a little script.
> >
> > Otherwise, where would it end? If you include http_proxy functionality in
> > git, why not also https_proxy functionality? And if that, why not
>
> And, BTW, why not? It may as well stop here.
Because it's not the purpose of git. It is the purpose of a tunnel. Let's
not make the mistake of Microsoft here: integrate everything until
everything breaks.
Ciao,
Dscho
^ permalink raw reply
* Re: [PATCH 2/2] Remember and use GIT_EXEC_PATH on exec()'s
From: Michal Ostrowski @ 2006-01-10 16:26 UTC (permalink / raw)
To: Andreas Ericsson; +Cc: Junio C Hamano, git
In-Reply-To: <43C3CC4A.4030805@op5.se>
On Tue, 2006-01-10 at 16:01 +0100, Andreas Ericsson wrote:
>
> This is the case in the git potty already. git.c must prepend
> --exec-path to $PATH, or the whole idea of being able to move scripts
> out of the $PATH fails (at least it fails without changing quite a few
> of the scripts).
One could make all the scripts depend on GIT_EXEC_PATH instead of PATH.
At build time one could generate wrapper functions in git-sh-setup:
function git-foo () {
$(GIT_EXEC_PATH)/git-foo $*;
}
Presuming that all scripts include git-sh-setup, no other shell script
changes would be needed.
>
> Since it's already in place in the potty and that's required to be in
> the $PATH, I think Junio's suggestion of running execlp("git", "git",
> ...) is a good one. It will add one extra fork() and execve() for each
> clone/pull/push, but that isn't much of an issue, really.
>
The patch I posted most recently does something comparable; all exec's
by C git programs go through exec_git_cmd, which actually implements the
"git potty" logic (and git.c itself uses exec_git_cmd). If there is to
be a consistent rule for how to exec a git program from a git C program,
I think that it's reasonable that there be an API to enforce it.
Note that the creation and use of such a function simply means that we
hide the logic that handles PATH/GIT_EXEC_PATH; how git_exec_cmd()
actually calls execve() and how PATH and GIT_EXEC_PATH are used is a
separate issue. When it comes to the former, I think it is best to have
all exec's of git programs go through an interface that imposes the same
PATH/GIT_EXEC_PATH logics. As to the latter, my only concern is that we
should never do 'setenv("PATH",....)'.
>
> > An approach that I think is better is to require all exec's of git
> > programs from within git programs to use a specific git interface,
> > rather than letting each one set up it's own exec parameters.
> >
>
> A better idea would be to teach {send,upload}-pack about $GIT_EXEX_PATH
> and export it from your shells rc-file.
>
My shell's rc-file doesn't get invoked when using ssh as a transport;
that's part of the problem.
>
> > Once you have that implemented, we can have a separate discussion of how
> > the executable is to be found;
> > - should we use PATH?
> > - should we change PATH?
> > - should we always exec using an absolute file name? (my preference)
> >
> > If a user invokes /home/user/bin/git-foo, and git-foo wants to call
> > git-bar, is it legitimate for git-foo to call /usr/local/bin/git-bar, or
> > should it require /home/user/bin/git-bar?
> >
>
> If a user invokes "/home/user/bin/git-foo" rather than
> "/home/user/bin/git foo" he/she will have to have the rest of the
> git-suite in the $PATH. Prepending whatever directory any git-* program
> happens to reside in to $PATH is not a good idea.
Isn't this exactly what git.c is doing currently via prepend_to_path()?
git programs exec other git programs, but they also exec non-git
programs. I think it is not appropriate to change PATH (via
prepend_to_path) because this may result in unexpected behavior when
exec'ing non-git programs:
Suppose git is installed in /usr/bin, where a "diff" resided.
I've got my own version of "diff" in /home/user/bin.
PATH=/home/user/bin:/usr/bin.
If git now tries to execute "diff", after having run
prepend_to_path(), /usr/bin/diff gets executed, not /home/user/bin/diff.
The user has set up PATH to ensure that /home/user/bin/diff is the diff,
but by mucking with PATH we subvert their intentions.
This is why in my original patch I tried to put the manipulations to
PATH only in points where I knew that it would only affect the exec'ing
of a git program.
>
>
> > Should the same rules be applied to the shell scripts? (In which case
> > we'd want to do something like s:git-:$(GIT_EXEC_PATH)/git-:g.)
> >
>
> All shell-scripts (that I'm aware of) are porcelainish. They should be
> run through the git potty and thus should always run the git-programs
> from the same release as they themselves were built from regardless of
> whether they call them through the potty or directly. This is both sane
> and simple. It was also one of the reasons that the 'git' program was
> implemented in C to begin with.
>
As described above, we can have shells scripts "always run the
git-programs from the same release as they themselves were built from"
without ever changing PATH.
--
Michal Ostrowski <mostrows@watson.ibm.com>
^ permalink raw reply
* Re: undoing changes with git-checkout -f
From: Alex Riesen @ 2006-01-10 16:17 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Joel Becker, Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.63.0601101549360.26054@wbgn013.biozentrum.uni-wuerzburg.de>
On 1/10/06, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> > Can we teach the git:// fetch program to use CONNECT over HTTP
> > proxies? rsync can do this, but git:// cannot, so firewalls that block
> > 9418 mean we use rsync://
>
> I think it is good and well with the proxy command support. Everybody can
> write a little script.
>
> Otherwise, where would it end? If you include http_proxy functionality in
> git, why not also https_proxy functionality? And if that, why not
And, BTW, why not? It may as well stop here.
^ 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