* [PATCH 5/6] have index-pack create .keep file more carefully
From: Nicolas Pitre @ 2006-11-01 22:06 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Nicolas Pitre
In-Reply-To: <1162418786390-git-send-email-nico@cam.org>
If by chance we receive a pack which content (list of objects) matches
another pack that we already have, and if that pack is marked with a
.keep file, then we should not overwrite it.
Signed-off-by: Nicolas Pitre <nico@cam.org>
---
index-pack.c | 17 ++++++++++-------
1 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/index-pack.c b/index-pack.c
index a3b55f9..8d64a88 100644
--- a/index-pack.c
+++ b/index-pack.c
@@ -788,14 +788,17 @@ static void final(const char *final_pack
get_object_directory(), sha1_to_hex(sha1));
keep_name = name;
}
- keep_fd = open(keep_name, O_RDWR | O_CREAT, 0600);
- if (keep_fd < 0)
- die("cannot write keep file");
- if (keep_msg_len > 0) {
- write_or_die(keep_fd, keep_msg, keep_msg_len);
- write_or_die(keep_fd, "\n", 1);
+ keep_fd = open(keep_name, O_RDWR|O_CREAT|O_EXCL, 0600);
+ if (keep_fd < 0) {
+ if (errno != EEXIST)
+ die("cannot write keep file");
+ } else {
+ if (keep_msg_len > 0) {
+ write_or_die(keep_fd, keep_msg, keep_msg_len);
+ write_or_die(keep_fd, "\n", 1);
+ }
+ close(keep_fd);
}
- close(keep_fd);
}
if (final_pack_name != curr_pack_name) {
--
1.4.3.3.g87b2-dirty
^ permalink raw reply related
* [PATCH 6/6] remove .keep pack lock files when done with refs update
From: Nicolas Pitre @ 2006-11-01 22:06 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Nicolas Pitre
In-Reply-To: <11624187871572-git-send-email-nico@cam.org>
This makes both git-fetch and git-push (fetch-pack and receive-pack)
safe against a possible race with aparallel git-repack -a -d that could
prune the new pack while it is not yet referenced, and remove the .keep
file after refs have been updated.
Signed-off-by: Nicolas Pitre <nico@cam.org>
---
Documentation/git-index-pack.txt | 11 ++++
git-fetch.sh | 10 ++++-
index-pack.c | 38 +++++++++------
receive-pack.c | 96 +++++++++++++++++++++++++++++---------
4 files changed, 116 insertions(+), 39 deletions(-)
diff --git a/Documentation/git-index-pack.txt b/Documentation/git-index-pack.txt
index 1235416..2229ee8 100644
--- a/Documentation/git-index-pack.txt
+++ b/Documentation/git-index-pack.txt
@@ -69,6 +69,17 @@ OPTIONS
locate any which have outlived their usefulness.
+Note
+----
+
+Once the index has been created, the list of object names is sorted
+and the SHA1 hash of that list is printed to stdout. If --stdin was
+also used then this is prefixed by either "pack\t", or "keep\t" if a
+new .keep file was successfully created. This is useful to remove a
+.keep file used as a lock to prevent the race with gitlink:git-repack[1]
+mentioned above.
+
+
Author
------
Written by Sergey Vlasov <vsu@altlinux.ru>
diff --git a/git-fetch.sh b/git-fetch.sh
index 2b5538f..e8ce296 100755
--- a/git-fetch.sh
+++ b/git-fetch.sh
@@ -51,7 +51,7 @@ do
verbose=Yes
;;
-k|--k|--ke|--kee|--keep)
- keep=--keep
+ keep=-k -k
;;
--reflog-action=*)
rloga=`expr "z$1" : 'z-[^=]*=\(.*\)'`
@@ -368,6 +368,7 @@ fetch_main () {
;; # we are already done.
*)
( : subshell because we muck with IFS
+ pack_lockfile=
IFS=" $LF"
(
git-fetch-pack --thin $exec $keep "$remote" $rref || echo failed "$remote"
@@ -378,6 +379,12 @@ fetch_main () {
failed)
echo >&2 "Fetch failure: $remote"
exit 1 ;;
+ # special line coming from index-pack with the pack name
+ pack)
+ continue ;;
+ keep)
+ pack_lockfile="$GIT_OBJECT_DIRECTORY/pack/pack-$remote_name.keep"
+ continue ;;
esac
found=
single_force=
@@ -408,6 +415,7 @@ fetch_main () {
append_fetch_head "$sha1" "$remote" \
"$remote_name" "$remote_nick" "$local_name" "$not_for_merge"
done
+ if [ "$pack_lockfile" ]; then rm -f "$pack_lockfile"; fi
) || exit ;;
esac
diff --git a/index-pack.c b/index-pack.c
index 8d64a88..042aea8 100644
--- a/index-pack.c
+++ b/index-pack.c
@@ -757,6 +757,7 @@ static void final(const char *final_pack
const char *keep_name, const char *keep_msg,
unsigned char *sha1)
{
+ char *report = "pack";
char name[PATH_MAX];
int err;
@@ -767,18 +768,6 @@ static void final(const char *final_pack
if (err)
die("error while closing pack file: %s", strerror(errno));
chmod(curr_pack_name, 0444);
-
- /*
- * Let's just mimic git-unpack-objects here and write
- * the last part of the buffer to stdout.
- */
- while (input_len) {
- err = xwrite(1, input_buffer + input_offset, input_len);
- if (err <= 0)
- break;
- input_len -= err;
- input_offset += err;
- }
}
if (keep_msg) {
@@ -798,6 +787,7 @@ static void final(const char *final_pack
write_or_die(keep_fd, "\n", 1);
}
close(keep_fd);
+ report = "keep";
}
}
@@ -821,6 +811,27 @@ static void final(const char *final_pack
if (move_temp_to_file(curr_index_name, final_index_name))
die("cannot store index file");
}
+
+ if (!from_stdin) {
+ printf("%s\n", sha1_to_hex(sha1));
+ } else {
+ char buf[48];
+ int len = snprintf(buf, sizeof(buf), "%s\t%s\n",
+ report, sha1_to_hex(sha1));
+ xwrite(1, buf, len);
+
+ /*
+ * Let's just mimic git-unpack-objects here and write
+ * the last part of the input buffer to stdout.
+ */
+ while (input_len) {
+ err = xwrite(1, input_buffer + input_offset, input_len);
+ if (err <= 0)
+ break;
+ input_len -= err;
+ input_offset += err;
+ }
+ }
}
int main(int argc, char **argv)
@@ -937,8 +948,5 @@ int main(int argc, char **argv)
free(index_name_buf);
free(keep_name_buf);
- if (!from_stdin)
- printf("%s\n", sha1_to_hex(sha1));
-
return 0;
}
diff --git a/receive-pack.c b/receive-pack.c
index be4c3fb..8bb5683 100644
--- a/receive-pack.c
+++ b/receive-pack.c
@@ -3,8 +3,10 @@
#include "refs.h"
#include "pkt-line.h"
#include "run-command.h"
+#include "exec_cmd.h"
#include "commit.h"
#include "object.h"
+#include <sys/wait.h>
static const char receive_pack_usage[] = "git-receive-pack <git-dir>";
@@ -251,12 +253,13 @@ static const char *parse_pack_header(str
return NULL;
}
+static const char *pack_lockfile;
+
static const char *unpack(void)
{
struct pack_header hdr;
const char *hdr_err;
char hdr_arg[38];
- int code;
hdr_err = parse_pack_header(&hdr);
if (hdr_err)
@@ -265,33 +268,13 @@ static const char *unpack(void)
ntohl(hdr.hdr_version), ntohl(hdr.hdr_entries));
if (ntohl(hdr.hdr_entries) < unpack_limit) {
+ int code;
const char *unpacker[3];
unpacker[0] = "unpack-objects";
unpacker[1] = hdr_arg;
unpacker[2] = NULL;
code = run_command_v_opt(1, unpacker, RUN_GIT_CMD);
- } else {
- const char *keeper[6];
- char my_host[255], keep_arg[128 + 255];
-
- if (gethostname(my_host, sizeof(my_host)))
- strcpy(my_host, "localhost");
- snprintf(keep_arg, sizeof(keep_arg),
- "--keep=receive-pack %i on %s",
- getpid(), my_host);
-
- keeper[0] = "index-pack";
- keeper[1] = "--stdin";
- keeper[2] = "--fix-thin";
- keeper[3] = hdr_arg;
- keeper[4] = keep_arg;
- keeper[5] = NULL;
- code = run_command_v_opt(1, keeper, RUN_GIT_CMD);
- if (!code)
- reprepare_packed_git();
- }
-
- switch (code) {
+ switch (code) {
case 0:
return NULL;
case -ERR_RUN_COMMAND_FORK:
@@ -308,6 +291,71 @@ static const char *unpack(void)
return "unpacker died strangely";
default:
return "unpacker exited with error code";
+ }
+ } else {
+ const char *keeper[6];
+ int fd[2], s, len, status;
+ pid_t pid;
+ char keep_arg[256];
+ char packname[46];
+
+ s = sprintf(keep_arg, "--keep=receive-pack %i on ", getpid());
+ if (gethostname(keep_arg + s, sizeof(keep_arg) - s))
+ strcpy(keep_arg + s, "localhost");
+
+ keeper[0] = "index-pack";
+ keeper[1] = "--stdin";
+ keeper[2] = "--fix-thin";
+ keeper[3] = hdr_arg;
+ keeper[4] = keep_arg;
+ keeper[5] = NULL;
+
+ if (pipe(fd) < 0)
+ return "index-pack pipe failed";
+ pid = fork();
+ if (pid < 0)
+ return "index-pack fork failed";
+ if (!pid) {
+ dup2(fd[1], 1);
+ close(fd[1]);
+ close(fd[0]);
+ execv_git_cmd(keeper);
+ die("execv of index-pack failed");
+ }
+ close(fd[1]);
+
+ /*
+ * The first thing we expects from index-pack's output
+ * is "pack\t%40s\n" or "keep\t%40s\n" (46 bytes) where
+ * %40s is the newly created pack SHA1 name. In the "keep"
+ * case, we need it to remove the corresponding .keep file
+ * later on. If we don't get that then tough luck with it.
+ */
+ for (len = 0;
+ len < 46 && (s = xread(fd[0], packname+len, 46-len)) > 0;
+ len += s);
+ close(fd[0]);
+ if (len == 46 && packname[45] == '\n' &&
+ memcmp(packname, "keep\t", 5) == 0) {
+ char path[PATH_MAX];
+ packname[45] = 0;
+ snprintf(path, sizeof(path), "%s/pack/pack-%s.keep",
+ get_object_directory(), packname + 5);
+ pack_lockfile = xstrdup(path);
+ }
+
+ /* Then wrap our index-pack process. */
+ while (waitpid(pid, &status, 0) < 0)
+ if (errno != EINTR)
+ return "waitpid failed";
+ if (WIFEXITED(status)) {
+ int code = WEXITSTATUS(status);
+ if (code)
+ return "index-pack exited with error code";
+ reprepare_packed_git();
+ return NULL;
+ }
+ return "index-pack abnormal exit";
}
}
@@ -363,6 +411,8 @@ int main(int argc, char **argv)
const char *unpack_status = unpack();
if (!unpack_status)
execute_commands();
+ if (pack_lockfile)
+ unlink(pack_lockfile);
if (report_status)
report(unpack_status);
}
--
1.4.3.3.g87b2-dirty
^ permalink raw reply related
* [PATCH 3/6] git-fetch can use both --thin and --keep with fetch-pack now
From: Nicolas Pitre @ 2006-11-01 22:06 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Nicolas Pitre
In-Reply-To: <11624187853865-git-send-email-nico@cam.org>
Signed-off-by: Nicolas Pitre <nico@cam.org>
---
git-fetch.sh | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/git-fetch.sh b/git-fetch.sh
index 539dff6..2b5538f 100755
--- a/git-fetch.sh
+++ b/git-fetch.sh
@@ -20,7 +20,7 @@ verbose=
update_head_ok=
exec=
upload_pack=
-keep=--thin
+keep=
while case "$#" in 0) break ;; esac
do
case "$1" in
@@ -370,7 +370,7 @@ fetch_main () {
( : subshell because we muck with IFS
IFS=" $LF"
(
- git-fetch-pack $exec $keep "$remote" $rref || echo failed "$remote"
+ git-fetch-pack --thin $exec $keep "$remote" $rref || echo failed "$remote"
) |
while read sha1 remote_name
do
--
1.4.3.3.g87b2-dirty
^ permalink raw reply related
* [PATCH 2/6] Teach receive-pack how to keep pack files based on object count.
From: Nicolas Pitre @ 2006-11-01 22:06 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Shawn Pearce
In-Reply-To: <11624187853116-git-send-email-nico@cam.org>
From: Shawn Pearce <spearce@spearce.org>
Since keeping a pushed pack or exploding it into loose objects
should be a local repository decision this teaches receive-pack
to decide if it should call unpack-objects or index-pack --stdin
--fix-thin based on the setting of receive.unpackLimit and the
number of objects contained in the received pack.
If the number of objects (hdr_entries) in the received pack is
below the value of receive.unpackLimit (which is 5000 by default)
then we unpack-objects as we have in the past.
If the hdr_entries >= receive.unpackLimit then we call index-pack and
ask it to include our pid and hostname in the .keep file to make it
easier to identify why a given pack has been kept in the repository.
Currently this leaves every received pack as a kept pack. We really
don't want that as received packs will tend to be small. Instead we
want to delete the .keep file automatically after all refs have
been updated. That is being left as room for future improvement.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
Documentation/config.txt | 11 +++++-
cache.h | 1 +
receive-pack.c | 98 +++++++++++++++++++++++++++++++++++++---------
sha1_file.c | 2 +-
4 files changed, 91 insertions(+), 21 deletions(-)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index d9e73da..9d3c71c 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -301,7 +301,16 @@ imap::
The configuration variables in the 'imap' section are described
in gitlink:git-imap-send[1].
-receive.denyNonFastforwads::
+receive.unpackLimit::
+ If the number of objects received in a push is below this
+ limit then the objects will be unpacked into loose object
+ files. However if the number of received objects equals or
+ exceeds this limit then the received pack will be stored as
+ a pack, after adding any missing delta bases. Storing the
+ pack from a push can make the push operation complete faster,
+ especially on slow filesystems.
+
+receive.denyNonFastForwards::
If set to true, git-receive-pack will deny a ref update which is
not a fast forward. Use this to prevent such an update via a push,
even if that push is forced. This configuration variable is
diff --git a/cache.h b/cache.h
index e997a85..6cb7e1d 100644
--- a/cache.h
+++ b/cache.h
@@ -376,6 +376,7 @@ extern struct packed_git *parse_pack_ind
char *idx_path);
extern void prepare_packed_git(void);
+extern void reprepare_packed_git(void);
extern void install_packed_git(struct packed_git *pack);
extern struct packed_git *find_sha1_pack(const unsigned char *sha1,
diff --git a/receive-pack.c b/receive-pack.c
index e2ba8a8..be4c3fb 100644
--- a/receive-pack.c
+++ b/receive-pack.c
@@ -1,4 +1,5 @@
#include "cache.h"
+#include "pack.h"
#include "refs.h"
#include "pkt-line.h"
#include "run-command.h"
@@ -7,9 +8,8 @@
static const char receive_pack_usage[] = "git-receive-pack <git-dir>";
-static const char *unpacker[] = { "unpack-objects", NULL };
-
static int deny_non_fast_forwards = 0;
+static int unpack_limit = 5000;
static int report_status;
static char capabilities[] = "report-status";
@@ -25,6 +25,12 @@ static int receive_pack_config(const cha
return 0;
}
+ if (strcmp(var, "receive.unpacklimit") == 0)
+ {
+ unpack_limit = git_config_int(var, value);
+ return 0;
+ }
+
return 0;
}
@@ -227,27 +233,81 @@ static void read_head_info(void)
}
}
+static const char *parse_pack_header(struct pack_header *hdr)
+{
+ char *c = (char*)hdr;
+ ssize_t remaining = sizeof(struct pack_header);
+ do {
+ ssize_t r = xread(0, c, remaining);
+ if (r <= 0)
+ return "eof before pack header was fully read";
+ remaining -= r;
+ c += r;
+ } while (remaining > 0);
+ if (hdr->hdr_signature != htonl(PACK_SIGNATURE))
+ return "protocol error (pack signature mismatch detected)";
+ if (!pack_version_ok(hdr->hdr_version))
+ return "protocol error (pack version unsupported)";
+ return NULL;
+}
+
static const char *unpack(void)
{
- int code = run_command_v_opt(1, unpacker, RUN_GIT_CMD);
+ struct pack_header hdr;
+ const char *hdr_err;
+ char hdr_arg[38];
+ int code;
+
+ hdr_err = parse_pack_header(&hdr);
+ if (hdr_err)
+ return hdr_err;
+ snprintf(hdr_arg, sizeof(hdr_arg), "--pack_header=%u,%u",
+ ntohl(hdr.hdr_version), ntohl(hdr.hdr_entries));
+
+ if (ntohl(hdr.hdr_entries) < unpack_limit) {
+ const char *unpacker[3];
+ unpacker[0] = "unpack-objects";
+ unpacker[1] = hdr_arg;
+ unpacker[2] = NULL;
+ code = run_command_v_opt(1, unpacker, RUN_GIT_CMD);
+ } else {
+ const char *keeper[6];
+ char my_host[255], keep_arg[128 + 255];
+
+ if (gethostname(my_host, sizeof(my_host)))
+ strcpy(my_host, "localhost");
+ snprintf(keep_arg, sizeof(keep_arg),
+ "--keep=receive-pack %i on %s",
+ getpid(), my_host);
+
+ keeper[0] = "index-pack";
+ keeper[1] = "--stdin";
+ keeper[2] = "--fix-thin";
+ keeper[3] = hdr_arg;
+ keeper[4] = keep_arg;
+ keeper[5] = NULL;
+ code = run_command_v_opt(1, keeper, RUN_GIT_CMD);
+ if (!code)
+ reprepare_packed_git();
+ }
switch (code) {
- case 0:
- return NULL;
- case -ERR_RUN_COMMAND_FORK:
- return "unpack fork failed";
- case -ERR_RUN_COMMAND_EXEC:
- return "unpack execute failed";
- case -ERR_RUN_COMMAND_WAITPID:
- return "waitpid failed";
- case -ERR_RUN_COMMAND_WAITPID_WRONG_PID:
- return "waitpid is confused";
- case -ERR_RUN_COMMAND_WAITPID_SIGNAL:
- return "unpacker died of signal";
- case -ERR_RUN_COMMAND_WAITPID_NOEXIT:
- return "unpacker died strangely";
- default:
- return "unpacker exited with error code";
+ case 0:
+ return NULL;
+ case -ERR_RUN_COMMAND_FORK:
+ return "unpack fork failed";
+ case -ERR_RUN_COMMAND_EXEC:
+ return "unpack execute failed";
+ case -ERR_RUN_COMMAND_WAITPID:
+ return "waitpid failed";
+ case -ERR_RUN_COMMAND_WAITPID_WRONG_PID:
+ return "waitpid is confused";
+ case -ERR_RUN_COMMAND_WAITPID_SIGNAL:
+ return "unpacker died of signal";
+ case -ERR_RUN_COMMAND_WAITPID_NOEXIT:
+ return "unpacker died strangely";
+ default:
+ return "unpacker exited with error code";
}
}
diff --git a/sha1_file.c b/sha1_file.c
index 5e6c8b8..7bda2d4 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -663,7 +663,7 @@ void prepare_packed_git(void)
prepare_packed_git_run_once = 1;
}
-static void reprepare_packed_git(void)
+void reprepare_packed_git(void)
{
prepare_packed_git_run_once = 0;
prepare_packed_git();
--
1.4.3.3.g87b2-dirty
^ permalink raw reply related
* [PATCH 1/6] Allow pack header preprocessing before unpack-objects/index-pack.
From: Nicolas Pitre @ 2006-11-01 22:06 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Nicolas Pitre
Some applications which invoke unpack-objects or index-pack --stdin
may want to examine the pack header to determine the number of
objects contained in the pack and use that value to determine which
executable to invoke to handle the rest of the pack stream.
However if the caller consumes the pack header from the input stream
then its no longer available for unpack-objects or index-pack --stdin,
both of which need the version and object count to process the stream.
This change introduces --pack_header=ver,cnt as a command line option
that the caller can supply to indicate it has already consumed the
pack header and what version and object count were found in that
header. As this option is only meant for low level applications
such as receive-pack we are not documenting it at this time.
Signed-off-by: Nicolas Pitre <nico@cam.org>
---
Patch description text shamelessly stolen from a similar patch from
Shawn Pearce <spearce@spearce.org>.
builtin-unpack-objects.c | 15 +++++++++++++++
index-pack.c | 13 +++++++++++++
2 files changed, 28 insertions(+), 0 deletions(-)
diff --git a/builtin-unpack-objects.c b/builtin-unpack-objects.c
index 74a90c1..e6d7574 100644
--- a/builtin-unpack-objects.c
+++ b/builtin-unpack-objects.c
@@ -371,6 +371,21 @@ int cmd_unpack_objects(int argc, const c
recover = 1;
continue;
}
+ if (!strncmp(arg, "--pack_header=", 14)) {
+ struct pack_header *hdr;
+ char *c;
+
+ hdr = (struct pack_header *)buffer;
+ hdr->hdr_signature = htonl(PACK_SIGNATURE);
+ hdr->hdr_version = htonl(strtoul(arg + 14, &c, 10));
+ if (*c != ',')
+ die("bad %s", arg);
+ hdr->hdr_entries = htonl(strtoul(c + 1, &c, 10));
+ if (*c)
+ die("bad %s", arg);
+ len = sizeof(*hdr);
+ continue;
+ }
usage(unpack_usage);
}
diff --git a/index-pack.c b/index-pack.c
index b37dd78..a3b55f9 100644
--- a/index-pack.c
+++ b/index-pack.c
@@ -841,6 +841,19 @@ int main(int argc, char **argv)
keep_msg = "";
} else if (!strncmp(arg, "--keep=", 7)) {
keep_msg = arg + 7;
+ } else if (!strncmp(arg, "--pack_header=", 14)) {
+ struct pack_header *hdr;
+ char *c;
+
+ hdr = (struct pack_header *)input_buffer;
+ hdr->hdr_signature = htonl(PACK_SIGNATURE);
+ hdr->hdr_version = htonl(strtoul(arg + 14, &c, 10));
+ if (*c != ',')
+ die("bad %s", arg);
+ hdr->hdr_entries = htonl(strtoul(c + 1, &c, 10));
+ if (*c)
+ die("bad %s", arg);
+ input_len = sizeof(*hdr);
} else if (!strcmp(arg, "-v")) {
verbose = 1;
} else if (!strcmp(arg, "-o")) {
--
1.4.3.3.g87b2-dirty
^ permalink raw reply related
* Re: Problem with git-push
From: Florent Thoumie @ 2006-11-01 22:54 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Johannes Schindelin, git
In-Reply-To: <7v8xiu3ksl.fsf@assigned-by-dhcp.cox.net>
[-- Attachment #1: Type: text/plain, Size: 1443 bytes --]
On Wed, 2006-11-01 at 13:43 -0800, Junio C Hamano wrote:
> Junio C Hamano <junkio@cox.net> writes:
>
> > Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> >
> >>> but more importantly, if the directory in question was created by
> >>> somebody else, I do not think this chmod() would succeed even if you are
> >>> in the same group as the owner (i.e. previous creator) of the directory.
> >>
> >> But if somebody else created it, it should already have the correct
> >> permissions in the first place (unless the user played around with them,
> >> which is not a pilot error, but a willfull pointing of the barrel in the
> >> general direction of your knee).
> >
> > True; I think the yesterday's analysis is still incomplete. I
> > haven't reached the point where I can explain "is a directory".
> > If the directory was there and mkdir() failed (but we do not
> > check its return value), it would have set errno to EEXIST not
> > to EISDIR. There is something else going on.
>
> Actually, Florent's said the directory permission was screwed up
> to begin with, so after following the code a bit more I can see
> why it said "is a directory".
I screwed the perms. I have a cron job that does automatic imports and
it's running as root. I've been lured by the fact that it uses my name
and email address to do those imports, so I thought it was running under
my unprivileged account.
Florent
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 187 bytes --]
^ permalink raw reply
* Re: Problem with git-push
From: Junio C Hamano @ 2006-11-01 21:43 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: git, Florent Thoumie
In-Reply-To: <7v4ptj5ghj.fsf@assigned-by-dhcp.cox.net>
Junio C Hamano <junkio@cox.net> writes:
> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
>
>>> but more importantly, if the directory in question was created by
>>> somebody else, I do not think this chmod() would succeed even if you are
>>> in the same group as the owner (i.e. previous creator) of the directory.
>>
>> But if somebody else created it, it should already have the correct
>> permissions in the first place (unless the user played around with them,
>> which is not a pilot error, but a willfull pointing of the barrel in the
>> general direction of your knee).
>
> True; I think the yesterday's analysis is still incomplete. I
> haven't reached the point where I can explain "is a directory".
> If the directory was there and mkdir() failed (but we do not
> check its return value), it would have set errno to EEXIST not
> to EISDIR. There is something else going on.
Actually, Florent's said the directory permission was screwed up
to begin with, so after following the code a bit more I can see
why it said "is a directory".
mkdir() may have failed because somebody else had a directory
there, perhaps with wrong permission; link_temp_to_file()
correctly fails from adjust_shared_perm() (because the directory
had incorrect permission that it cannot fix), returns -2 with
truncated filename "object/2d", back to move_temp_to_file(), and
-2 is not EEXIST so it tries to rename the temporary file to
that directory, which would also fail and sets ret to errno
(which now is EISDIR). After unlinking the temporary file, we
notice that ret is EISDIR and reports the failure.
So there is not much more to explain, other than why mkdir()
failed in the first place. Previous driver error?
I think idempotent chmod() on somebody else's file or directory
would fail, so this may be a safer addition to the codepath in
question.
diff --git a/path.c b/path.c
index bb89fb0..b82f194 100644
--- a/path.c
+++ b/path.c
@@ -279,7 +279,7 @@ int adjust_shared_perm(const char *path)
: 0));
if (S_ISDIR(mode))
mode |= S_ISGID;
- if (chmod(path, mode) < 0)
+ if (mode != st.st_mode && chmod(path, mode) < 0)
return -2;
return 0;
}
^ permalink raw reply related
* Re: Restore a single file in the index back to HEAD
From: Andy Parkins @ 2006-11-01 21:18 UTC (permalink / raw)
To: git
In-Reply-To: <7vbqnq51v4.fsf@assigned-by-dhcp.cox.net>
On Wednesday 2006, November 01 20:49, Junio C Hamano wrote:
> >> git-reset [--hard | --mixed] HEAD^ oops/file1
> While that perfect makes sense from mechanical point of view, I
> am not sure what it _means_ to keep some paths from now
> abandoned future while having some other paths reset to the
> rewound commit, from the point of view of end-user operation.
Isn't that exactly what the user would be asking for when they are doing a
per-file reset? This is a contrived example as git makes it easier to do it
in far more sensible ways; but I've done this before now in subversion...
What if I want to try out some radical change? It goes like this:
x --- y --- z
Where x is some stable commit; y is a load of crazy changes; we discover that
the crazy changes are all fine except for one, and so want to rollback one
file, without yet commiting:
git-reset --hard HEAD^ frotz
Git would get frotz from HEAD^ and write it to the working directory and the
index (or just index with --mixed).
> In other words, I do not have a good explanation on what "git
> reset [--hard|--mixed] <commit> <path>..." does that I can write
> in the documentation.
--mixed
Resets the index but not the working tree (i.e., the changed files are
preserved but not marked for commit) and reports what has not been
updated. This is the default action. If <path> is given then only that
path will be reset to the state that <path> had in <commit-ish>. The
working tree will be untouched.
--hard
Matches the working tree and index to that of the tree being switched to.
Any changes to tracked files in the working tree since <commit-ish> are
lost. If <path> is given then only that path will be reset in both the
working tree and the index to the state that <path> had in <commit-ish>.
> Well, now I am not sure of anything anymore ;-).
I do hope I'm not being presumptuous with all the above. I feel a bit gobby
spouting off like I know what I'm talking about. Especially as I wrote
absolutely no part of git whatsoever :-)
Andy
--
Dr Andrew Parkins, M Eng (Hons), AMIEE
^ permalink raw reply
* Re: binary patch compatibility
From: Jakub Narebski @ 2006-11-01 21:10 UTC (permalink / raw)
To: git
In-Reply-To: <4b73d43f0611011303m3e58b227x1a0bd60a9719f9f8@mail.gmail.com>
John Rigby wrote:
> If I commit a new binary file to a repository and then use
> git-format-patch --binary to produce a patch the resulting patch file
> is not compatible with the patch command.
>
> Am I doing something wrong or is this not possible.
GNU patch doesn't understand git binary patch. git-apply does (as does
git-am). There is no universal binary diff format.
--
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
^ permalink raw reply
* binary patch compatibility
From: John Rigby @ 2006-11-01 21:03 UTC (permalink / raw)
To: git
If I commit a new binary file to a repository and then use
git-format-patch --binary to produce a patch the resulting patch file
is not compatible with the patch command.
Am I doing something wrong or is this not possible.
Thanks
^ permalink raw reply
* Re: branch builtin
From: Junio C Hamano @ 2006-11-01 20:50 UTC (permalink / raw)
To: Andy Whitcroft; +Cc: git
In-Reply-To: <454900F5.5050603@shadowen.org>
Andy Whitcroft <apw@shadowen.org> writes:
> Since the branch command moved built-in it no longer works in
> sub-directories. I've futzed with it and it seems adding RUN_SETUP to
> the command table for branch makes 'git branch' work. Is this safe to do?
"git branch" is usable only within a git repository, so
RUN_SETUP should be the sane thing to do. Thanks for noticing.
^ permalink raw reply
* Re: Restore a single file in the index back to HEAD
From: Junio C Hamano @ 2006-11-01 20:49 UTC (permalink / raw)
To: Andy Parkins; +Cc: git
In-Reply-To: <200611012029.41869.andyparkins@gmail.com>
Andy Parkins <andyparkins@gmail.com> writes:
> On Wednesday 2006, November 01 18:28, Junio C Hamano wrote:
>
>> So from that point of view, the above commandline perfectly
>> makes sense. However, giving anything but HEAD with path makes
>> us go "Huh?" It is unclear what this should mean:
>>
>> git-reset [--hard | --mixed] HEAD^ oops/file1
>
> I don't understand. Why wouldn't that mean reset oops/file1 to the state it
> had in HEAD^?
Path limiters everywhere in git means "do this only for paths
that match this pattern, and empty path means the pattern match
every path -- the command's behaviour is not different in any
other aspect between the case you gave no limiter and the case
you gave _all_ paths as limiters". So the other paths remain as
they were (both index and working tree), and HEAD needs to be
updated to HEAD^ in the above example.
While that perfect makes sense from mechanical point of view, I
am not sure what it _means_ to keep some paths from now
abandoned future while having some other paths reset to the
rewound commit, from the point of view of end-user operation.
In other words, I do not have a good explanation on what "git
reset [--hard|--mixed] <commit> <path>..." does that I can write
in the documentation.
Now I admit I am not the brightest in the git circle, but if I
have trouble understanding what it does, can we expect other
people to grok it?
>> On the other hand, we already have --again, so maybe we have
>> already passed the point of no return. So I am inclined to
>> agree with your "update-index --reset" approach, unless somebody
>> else injects sanity into me.
>
> Actually; you've talked me out of it. Given that git-reset is already
> porcelain, and none of the solutions are screaming "right"; it seems better
> to slightly bend git-reset than git-update-index.
Well, now I am not sure of anything anymore ;-).
^ permalink raw reply
* Re: Restore a single file in the index back to HEAD
From: Andy Parkins @ 2006-11-01 20:29 UTC (permalink / raw)
To: git
In-Reply-To: <7vpsc710oy.fsf@assigned-by-dhcp.cox.net>
On Wednesday 2006, November 01 18:28, Junio C Hamano wrote:
> So from that point of view, the above commandline perfectly
> makes sense. However, giving anything but HEAD with path makes
> us go "Huh?" It is unclear what this should mean:
>
> git-reset [--hard | --mixed] HEAD^ oops/file1
I don't understand. Why wouldn't that mean reset oops/file1 to the state it
had in HEAD^?
> Checkout is a working tree manipulator Porcelain, and as a side
> effect it has always updated the index. So it might make sense
> to give --index-only there:
>
> git checkout --index-only HEAD -- paths...
I think you're right that this is not the place - git-checkout is what one
uses to update your working directory, it's only a side-effect that the index
is updated - or we could argue that it is necessary that the index is updated
in order that checkout can do it's job.
> On the other hand, we already have --again, so maybe we have
> already passed the point of no return. So I am inclined to
> agree with your "update-index --reset" approach, unless somebody
> else injects sanity into me.
Actually; you've talked me out of it. Given that git-reset is already
porcelain, and none of the solutions are screaming "right"; it seems better
to slightly bend git-reset than git-update-index.
Andy
--
Dr Andrew Parkins, M Eng (Hons), AMIEE
^ permalink raw reply
* branch builtin
From: Andy Whitcroft @ 2006-11-01 20:17 UTC (permalink / raw)
To: Git Mailing List
Since the branch command moved built-in it no longer works in
sub-directories. I've futzed with it and it seems adding RUN_SETUP to
the command table for branch makes 'git branch' work. Is this safe to do?
^ permalink raw reply
* Re: How to view an old revision?
From: Andy Whitcroft @ 2006-11-01 19:02 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Matt McCutchen, git
In-Reply-To: <7vzmbb2m42.fsf@assigned-by-dhcp.cox.net>
Junio C Hamano wrote:
> Andy Whitcroft <apw@shadowen.org> writes:
>
>> Junio, I wonder if we should be changing the usage for this command
>> slightly. Currently, it mearly says <object> as the identifier for the
>> blob. Really this is <object-ish> as it supports symbolic naming in
>> addition to raw sha1's. I also feel it would be very helpful if
>> <commit-ish> and family were documented as a glossary section in main
>> git manpage.
>>
>> Something like this:
>>
>> <commit-ish>:: is an sha1 for a commit, or any symbolic name for a
>> commit (see SPECIFYING REVISIONS in git-rev-parse)
>>
>> What do people think. I can do the munging about if its seems like a
>> sane plan.
>
> When we really want an object of type <x>, we accept an object
> that is not of type <x> if there is a natural and unique
> dereferencing of that object to the type <x>. We use word
> <x-ish> to describe such an object that dereferences to <x>.
> For example, ls-tree is about listing tree contents (so we want
> a tree), but we accept a commit because the natural and unique
> dereferencing of a commit to a tree is to take its (toplevel)
> tree. We also accept a tag pointing at a commit because we can
> dereference it to the commit and then to its tree. Hence a tag
> that points at either commit or a tree, and a commit are
> tree-ish.
>
> <object> is an object which can be <commit>, <tree>, <tag> or
> <blob>. There is nothing -ish about it.
>
> I was actually reviewing the documentation of git-rev-parse and
> noticed that it talks about naming objects in the section called
> "SPECIFYING REVISIONS". The title implies that it is about
> committish (because we think of "revisions" as something that is
> used in walking commit ancestry chains), but it actually talks
> about naming objects of any type.
>
> It is a good and comprehensive list when viewed as "list of ways
> you can name an object", but both the title and the page the
> list appears in put unfair emphasis of commits for that purpose,
> and it is hard to realize that what you learned there applies to
> naming any type of objects. It is even harder to guess the list
> appears on that page, unless you are the one who is actively involved
> in the git list, when you want to know which manual page to look
> at in order to find out how you name an arbitrary object.
>
> We could either
>
> (1) retitle the list and move it to git.txt (Symbolic
> Identifiers), and refer to it from pages that describe
> commands that take object names;
>
> (2) retitle the list and make it an includable snippet, similar
> to the way Documentation/diff-format.txt is used from pages
> that describe diff commands, and include it everywhere.
>
> I am slightly in favor of the latter. Although it has a bloat
> factor in the generated documentation, docs are not novels and
> not meant to be read from cover to cover, and duplicating
> relevant information on each page is more useful than refering
> the reader to jump around in the documentation set.
I'll take a stab at this ...
^ permalink raw reply
* Re: Problem with git-push
From: Florent Thoumie @ 2006-11-01 19:57 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Johannes Schindelin
In-Reply-To: <7v64e0qclo.fsf@assigned-by-dhcp.cox.net>
[-- Attachment #1: Type: text/plain, Size: 658 bytes --]
On Tue, 2006-10-31 at 15:39 -0800, Junio C Hamano wrote:
> A quick workaround until we sort this out would be:
>
> - make sure all your developers have umask suitable for group
> work (i.e. second octal-digit from the right should be zero
> to give group members the same rights as you do).
>
> - run "chmod g+w .git/objects/??" in the shared repository.
I thought I checked on the remote (guess I only looked at my local
repo), but that was it, wrong perms.
Sorry if this is a dumb question but assuming i did 3 successive
git-push's, why is the object name changing from a try to another?
Thanks for the answer.
Florent
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 187 bytes --]
^ permalink raw reply
* Re: [PATCH 00/10] gitweb: Better quoting and New improved patchset view
From: Jakub Narebski @ 2006-11-01 18:52 UTC (permalink / raw)
To: git
In-Reply-To: <200610301953.01875.jnareb@gmail.com>
Jakub Narebski wrote:
> This series of patches is meant to introduce
> "New improved patchset view" in part-by-part
> case.
And thus endeth "New inproved patchset view" saga.
Patches in series:
[PATCH 01/10] gitweb: Better git-unquoting and gitweb-quoting of
pathnames
[PATCH 02/10] gitweb: Use '&iquot;' instead of '?' in esc_path
[PATCH 03/10] gitweb: Use 's' regexp modifier to secure against
filenames with LF
[PATCH 04/10] gitweb: Secure against commit-ish/tree-ish with
the same name as path
[PATCH 05/10] gitweb: New improved patchset view
[PATCH 06/10] gitweb: Remove redundant "blob" links from
git_difftree_body
[PATCH 07/10] gitweb: Output also empty patches in "commitdiff" view
[PATCH 08/10] gitweb: Fix two issues with quoted filenames
in git_patchset_body
[PATCH 09/10] gitweb: Better support for non-CSS aware web browsers
[PATCH 10/10] gitweb: New improved formatting of chunk header in diff
Diffstat:
gitweb/gitweb.css | 79 +++++++++--
gitweb/gitweb.perl | 378 ++++++++++++++++++++++++++++++++--------------------
2 files changed, 303 insertions(+), 154 deletions(-)
Shortlog:
Jakub Narebski (11):
gitweb: Better git-unquoting and gitweb-quoting of pathnames
gitweb: Use '&iquot;' instead of '?' in esc_path
gitweb: Use 's' regexp modifier to secure against filenames with LF
gitweb: Secure against commit-ish/tree-ish with the same name as path
gitweb: New improved patchset view
gitweb: Remove redundant "blob" links from git_difftree_body
gitweb: Output also empty patches in "commitdiff" view
gitweb: Fix two issues with quoted filenames in git_patchset_body
[*1*] gitweb: Remove "--" from "git ls-tree -z <hash> --", added overeagerily
gitweb: Better support for non-CSS aware web browsers
gitweb: New improved formatting of chunk header in diff
[*1*] Not send as patch itself, but as comment about patch
--
Jakub Narebski
^ permalink raw reply
* Re: Restore a single file in the index back to HEAD
From: Junio C Hamano @ 2006-11-01 18:28 UTC (permalink / raw)
To: Andy Parkins; +Cc: git
In-Reply-To: <200611010953.57360.andyparkins@gmail.com>
Andy Parkins <andyparkins@gmail.com> writes:
> As I mentioned in my original email, I was wishing for
>
> git-reset --mixed HEAD oops/file1
>
> But of course, that doesn't make any sense in the context of of git-reset,
> which is really only a HEAD manipulator with extras.
Well, reset historically is _not_ HEAD manipulator. It is the
primarily Porcelain-ish to recover the index and/or the working
tree that is in an undesired state.
So from that point of view, the above commandline perfectly
makes sense. However, giving anything but HEAD with path makes
us go "Huh?" It is unclear what this should mean:
git-reset [--hard | --mixed] HEAD^ oops/file1
Checkout is a working tree manipulator Porcelain, and as a side
effect it has always updated the index. So it might make sense
to give --index-only there:
git checkout --index-only HEAD -- paths...
But from UI and workflow point of view, I think the situation
under discussion is that the user wishes to _recover_ from an
earlier update-index that he did not want to do. Although
update-index is not designed as a UI but as a plumbing, it has
been used as such (and git-status output even suggests use of
it), so maybe it is not such a bad idea to bite the bullet and
declare that it now _is_ a Porcelain-ish. Then we can do what
you suggested (with missing <commit> defaulting to HEAD):
git update-index --reset [<commit>] -- paths...
I am not enthused by this avenue, though. I'd like to keep low
level plumbing as "tool to do only one thing and one thing well"
and update-index is as low level as you would get.
On the other hand, we already have --again, so maybe we have
already passed the point of no return. So I am inclined to
agree with your "update-index --reset" approach, unless somebody
else injects sanity into me.
^ permalink raw reply
* Re: How to view an old revision?
From: Matt McCutchen @ 2006-11-01 16:25 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Andy Whitcroft, git
In-Reply-To: <7vzmbb2m42.fsf@assigned-by-dhcp.cox.net>
On 11/1/06, Junio C Hamano <junkio@cox.net> wrote:
> I was actually reviewing the documentation of git-rev-parse and
> noticed that it talks about naming objects in the section called
> "SPECIFYING REVISIONS". The title implies that it is about
> committish (because we think of "revisions" as something that is
> used in walking commit ancestry chains), but it actually talks
> about naming objects of any type.
There's no way I would have known to look in git-rev-parse. My
git-rev-parse man page doesn't mention the colon syntax, but now I see
that part in git's gitweb; my man page must be too old. Either (1) or
(2) would have been enough for me to figure out that the colon syntax
would do what I wanted, but to grab the attention of the less
persistent user, it would be good to mention the particular case of
"git-cat-file <commit-ish>:<file>" in the git-cat-file man page.
^ permalink raw reply
* Re: Problem with git-push
From: Junio C Hamano @ 2006-11-01 16:21 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Florent Thoumie, git
In-Reply-To: <Pine.LNX.4.63.0611011205340.1670@wbgn013.biozentrum.uni-wuerzburg.de>
Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> How about this instead:
>
> - mkdir(filename, 0777);
> - if (adjust_shared_perm(filename))
> + if (!mkdir(filename, 0777) && adjust_shared_perm(filename)) {
> + *dir = '/';
> return -2;
> + }
Not really. See the comment above the code you just touched.
^ permalink raw reply
* Re: [PATCH] Introduce git-mirror, a tool for exactly mirroring another repository.
From: Junio C Hamano @ 2006-11-01 16:15 UTC (permalink / raw)
To: Sergey Vlasov; +Cc: git
In-Reply-To: <20061101151859.0e984d3f.vsu@altlinux.ru>
Sergey Vlasov <vsu@altlinux.ru> writes:
> What name format should be used for such saved refs? refs/old/`date -I`
> is not unique enough; probably `date --utc +%Y.%m.%d-%H.%M.%S`? And it
> would be good if multiple refs which were deleted or modified in a
> non-fast-forward way during a single operation (like git-mirror) would
> be saved together - which may be tricky if they are saved at the lower
> level (in update-ref).
>
> Adding the fast-forward check into update-ref also does not look nice,
> but this check is required for full safety.
I wasn't going to suggest doing the check or even naming at such
a low level. From the usability point of view, the caller
should decide if the discarded refs are even saved at all, and
if so in which namespace. That way commit_lock_file() can just
notice the old version of the locked file (it is always sitting
next to it) and hardlink the discarded one to the purgatory
before renaming the newly created .lock file there.
^ permalink raw reply
* Re: How to view an old revision?
From: Junio C Hamano @ 2006-11-01 16:00 UTC (permalink / raw)
To: Andy Whitcroft; +Cc: Matt McCutchen, git
In-Reply-To: <4548B32A.5030803@shadowen.org>
Andy Whitcroft <apw@shadowen.org> writes:
> Junio, I wonder if we should be changing the usage for this command
> slightly. Currently, it mearly says <object> as the identifier for the
> blob. Really this is <object-ish> as it supports symbolic naming in
> addition to raw sha1's. I also feel it would be very helpful if
> <commit-ish> and family were documented as a glossary section in main
> git manpage.
>
> Something like this:
>
> <commit-ish>:: is an sha1 for a commit, or any symbolic name for a
> commit (see SPECIFYING REVISIONS in git-rev-parse)
>
> What do people think. I can do the munging about if its seems like a
> sane plan.
When we really want an object of type <x>, we accept an object
that is not of type <x> if there is a natural and unique
dereferencing of that object to the type <x>. We use word
<x-ish> to describe such an object that dereferences to <x>.
For example, ls-tree is about listing tree contents (so we want
a tree), but we accept a commit because the natural and unique
dereferencing of a commit to a tree is to take its (toplevel)
tree. We also accept a tag pointing at a commit because we can
dereference it to the commit and then to its tree. Hence a tag
that points at either commit or a tree, and a commit are
tree-ish.
<object> is an object which can be <commit>, <tree>, <tag> or
<blob>. There is nothing -ish about it.
I was actually reviewing the documentation of git-rev-parse and
noticed that it talks about naming objects in the section called
"SPECIFYING REVISIONS". The title implies that it is about
committish (because we think of "revisions" as something that is
used in walking commit ancestry chains), but it actually talks
about naming objects of any type.
It is a good and comprehensive list when viewed as "list of ways
you can name an object", but both the title and the page the
list appears in put unfair emphasis of commits for that purpose,
and it is hard to realize that what you learned there applies to
naming any type of objects. It is even harder to guess the list
appears on that page, unless you are the one who is actively involved
in the git list, when you want to know which manual page to look
at in order to find out how you name an arbitrary object.
We could either
(1) retitle the list and move it to git.txt (Symbolic
Identifiers), and refer to it from pages that describe
commands that take object names;
(2) retitle the list and make it an includable snippet, similar
to the way Documentation/diff-format.txt is used from pages
that describe diff commands, and include it everywhere.
I am slightly in favor of the latter. Although it has a bloat
factor in the generated documentation, docs are not novels and
not meant to be read from cover to cover, and duplicating
relevant information on each page is more useful than refering
the reader to jump around in the documentation set.
^ permalink raw reply
* Re: [PATCH] Documentation: Update information about <format> in git-for-each-ref
From: Johannes Schindelin @ 2006-11-01 15:48 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Andreas Ericsson, git, Jakub Narebski
In-Reply-To: <7vac3b5gn8.fsf@assigned-by-dhcp.cox.net>
Hi,
On Wed, 1 Nov 2006, Junio C Hamano wrote:
> By the way, I think "a compares to b" is also a verb, not just
> "i compare a and b and found these differences".
In mathematics, "a compares to b" means that "a" and "b" are comparable.
There are uncomparable things like "0" and "sky". What is greater?
Of course, there is also a song with the title "Nothing compares to you"
which is sung by a native speaker, so go figure.
Ciao,
Dscho
^ permalink raw reply
* Re: Problem with git-push
From: Junio C Hamano @ 2006-11-01 15:33 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Florent Thoumie, git
In-Reply-To: <Pine.LNX.4.63.0611011205340.1670@wbgn013.biozentrum.uni-wuerzburg.de>
Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
>> but more importantly, if the directory in question was created by
>> somebody else, I do not think this chmod() would succeed even if you are
>> in the same group as the owner (i.e. previous creator) of the directory.
>
> But if somebody else created it, it should already have the correct
> permissions in the first place (unless the user played around with them,
> which is not a pilot error, but a willfull pointing of the barrel in the
> general direction of your knee).
True; I think the yesterday's analysis is still incomplete. I
haven't reached the point where I can explain "is a directory".
If the directory was there and mkdir() failed (but we do not
check its return value), it would have set errno to EEXIST not
to EISDIR. There is something else going on.
>> [jc: I am CC'ing Johannes to blame him on commit 457f06d6;
>> git-pickaxe is turning out to be quite handy ;-)
>
> I am hating the tool already.
Well, we could rename it to "git credit" ;-).
^ permalink raw reply
* Re: [PATCH] Documentation: Update information about <format> in git-for-each-ref
From: Junio C Hamano @ 2006-11-01 15:30 UTC (permalink / raw)
To: Andreas Ericsson; +Cc: git, Jakub Narebski
In-Reply-To: <454875AC.6060300@op5.se>
Andreas Ericsson <ae@op5.se> writes:
> ... For me it's the other
> way around, so I think of the above as "if it doesn't compare to this
> or that, then do this", but the "are equal to" meaning of "compare"
> isn't intuitive to me as I spent the first several years of my
> english-speaking life using "compare" exclusively as a verb.
<offtopic>
I think I should have said that "I force me to pronounce" and I
am trying to say the same thing as you said.
xxxcmp(a, b) literally is "compare a and b and give me the
result"; the result coming back as "true" when a and b are
different is counter-intuitive and I think it is so to
everybody, not limited to non-English speaking people. That's
why I force me to ignore the etymology of the "cmp" in the
function name and call that "a and b differs" or "subtract b
from a" depending on the context.
By the way, I think "a compares to b" is also a verb, not just
"i compare a and b and found these differences".
</offtopic>
^ 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