* Re: [PATCH 0/5] fork/exec removal series
From: Junio C Hamano @ 2007-09-30 20:20 UTC (permalink / raw)
To: Johannes Sixt; +Cc: gitster, git
In-Reply-To: <1191183001-5368-1-git-send-email-johannes.sixt@telecom.at>
Johannes Sixt <johannes.sixt@telecom.at> writes:
> Here is a series of patches that removes a number fork/exec pairs.
> They are replaced by delegating to start_command/finish_command/run_command.
> You can regard this as the beginning of the MinGW port integration.
Yay!
> Patch 2 depends on Patch 1; otherwise, there are no dependencies.
> The series goes on top of next (it touches str_buf stuff in connect.c).
Thanks for an advance warning.
I'll keep the series in my mailbox (promise) and queue it for
'pu' for now (but only if I have time), as I intend to merge the
strbuf stuff to 'master' soon.
^ permalink raw reply
* [PATCH 5/5] Use start_comand() in builtin-fetch-pack.c instead of explicit fork/exec.
From: Johannes Sixt @ 2007-09-30 20:10 UTC (permalink / raw)
To: gitster; +Cc: git, Johannes Sixt
In-Reply-To: <1191183001-5368-5-git-send-email-johannes.sixt@telecom.at>
Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
---
builtin-fetch-pack.c | 55 ++++++++++++++-----------------------------------
1 files changed, 16 insertions(+), 39 deletions(-)
diff --git a/builtin-fetch-pack.c b/builtin-fetch-pack.c
index 19c144d..d0eca2d 100644
--- a/builtin-fetch-pack.c
+++ b/builtin-fetch-pack.c
@@ -7,6 +7,7 @@
#include "pack.h"
#include "sideband.h"
#include "fetch-pack.h"
+#include "run-command.h"
static int transfer_unpack_limit = -1;
static int fetch_unpack_limit = -1;
@@ -499,11 +500,13 @@ static int get_pack(int xd[2], char **pack_lockfile)
char hdr_arg[256];
const char **av;
int do_keep = args.keep_pack;
- int keep_pipe[2];
+ struct child_process cmd;
side_pid = setup_sideband(fd, xd);
- av = argv;
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.argv = av = argv;
+
*hdr_arg = 0;
if (!args.keep_pack && unpack_limit) {
struct pack_header header;
@@ -519,8 +522,8 @@ static int get_pack(int xd[2], char **pack_lockfile)
}
if (do_keep) {
- if (pack_lockfile && pipe(keep_pipe))
- die("fetch-pack: pipe setup failure: %s", strerror(errno));
+ if (pack_lockfile)
+ cmd.out = -1;
*av++ = "index-pack";
*av++ = "--stdin";
if (!args.quiet && !args.no_progress)
@@ -544,43 +547,17 @@ static int get_pack(int xd[2], char **pack_lockfile)
*av++ = hdr_arg;
*av++ = NULL;
- pid = fork();
- if (pid < 0)
+ cmd.in = fd[0];
+ cmd.git_cmd = 1;
+ if (start_command(&cmd))
die("fetch-pack: unable to fork off %s", argv[0]);
- if (!pid) {
- dup2(fd[0], 0);
- if (do_keep && pack_lockfile) {
- dup2(keep_pipe[1], 1);
- close(keep_pipe[0]);
- close(keep_pipe[1]);
- }
- close(fd[0]);
- close(fd[1]);
- execv_git_cmd(argv);
- die("%s exec failed", argv[0]);
- }
- close(fd[0]);
close(fd[1]);
- if (do_keep && pack_lockfile) {
- close(keep_pipe[1]);
- *pack_lockfile = index_pack_lockfile(keep_pipe[0]);
- close(keep_pipe[0]);
- }
- while (waitpid(pid, &status, 0) < 0) {
- if (errno != EINTR)
- die("waiting for %s: %s", argv[0], strerror(errno));
- }
- if (WIFEXITED(status)) {
- int code = WEXITSTATUS(status);
- if (code)
- die("%s died with error code %d", argv[0], code);
- return 0;
- }
- if (WIFSIGNALED(status)) {
- int sig = WTERMSIG(status);
- die("%s died of signal %d", argv[0], sig);
- }
- die("%s died of unnatural causes %d", argv[0], status);
+ if (do_keep && pack_lockfile)
+ *pack_lockfile = index_pack_lockfile(cmd.out);
+
+ if (finish_command(&cmd))
+ die("%s failed", argv[0]);
+ return 0;
}
static struct ref *do_fetch_pack(int fd[2],
--
1.5.3.3.1134.gee562
^ permalink raw reply related
* [PATCH 1/5] Change git_connect() to return a struct child_process instead of a pid_t.
From: Johannes Sixt @ 2007-09-30 20:09 UTC (permalink / raw)
To: gitster; +Cc: git, Johannes Sixt
In-Reply-To: <1191183001-5368-1-git-send-email-johannes.sixt@telecom.at>
This prepares the API of git_connect() and finish_connect() to operate on
a struct child_process. Currently, we just use that object as a placeholder
for the pid that we used to return. A follow-up patch will change the
implementation of git_connect() and finish_connect() to make full use
of the object.
Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
---
builtin-archive.c | 8 +++-----
builtin-fetch-pack.c | 8 +++-----
cache.h | 4 ++--
connect.c | 28 +++++++++++++++-------------
peek-remote.c | 8 +++-----
send-pack.c | 8 +++-----
transport.c | 9 ++-------
7 files changed, 31 insertions(+), 42 deletions(-)
diff --git a/builtin-archive.c b/builtin-archive.c
index 04385de..76db6cf 100644
--- a/builtin-archive.c
+++ b/builtin-archive.c
@@ -30,7 +30,7 @@ static int run_remote_archiver(const char *remote, int argc,
{
char *url, buf[LARGE_PACKET_MAX];
int fd[2], i, len, rv;
- pid_t pid;
+ struct child_process *chld;
const char *exec = "git-upload-archive";
int exec_at = 0;
@@ -46,9 +46,7 @@ static int run_remote_archiver(const char *remote, int argc,
}
url = xstrdup(remote);
- pid = git_connect(fd, url, exec, 0);
- if (pid < 0)
- return pid;
+ chld = git_connect(fd, url, exec, 0);
for (i = 1; i < argc; i++) {
if (i == exec_at)
@@ -76,7 +74,7 @@ static int run_remote_archiver(const char *remote, int argc,
rv = recv_sideband("archive", fd[0], 1, 2);
close(fd[0]);
close(fd[1]);
- rv |= finish_connect(pid);
+ rv |= finish_connect(chld);
return !!rv;
}
diff --git a/builtin-fetch-pack.c b/builtin-fetch-pack.c
index 8f25d50..19c144d 100644
--- a/builtin-fetch-pack.c
+++ b/builtin-fetch-pack.c
@@ -762,7 +762,7 @@ struct ref *fetch_pack(struct fetch_pack_args *my_args,
{
int i, ret;
int fd[2];
- pid_t pid;
+ struct child_process *chld;
struct ref *ref;
struct stat st;
@@ -773,16 +773,14 @@ struct ref *fetch_pack(struct fetch_pack_args *my_args,
st.st_mtime = 0;
}
- pid = git_connect(fd, (char *)dest, uploadpack,
+ chld = git_connect(fd, (char *)dest, uploadpack,
args.verbose ? CONNECT_VERBOSE : 0);
- if (pid < 0)
- return NULL;
if (heads && nr_heads)
nr_heads = remove_duplicates(nr_heads, heads);
ref = do_fetch_pack(fd, nr_heads, heads, pack_lockfile);
close(fd[0]);
close(fd[1]);
- ret = finish_connect(pid);
+ ret = finish_connect(chld);
if (!ret && nr_heads) {
/* If the heads to pull were given, we should have
diff --git a/cache.h b/cache.h
index 27485d3..32ce8a7 100644
--- a/cache.h
+++ b/cache.h
@@ -503,8 +503,8 @@ struct ref {
#define REF_TAGS (1u << 2)
#define CONNECT_VERBOSE (1u << 0)
-extern pid_t git_connect(int fd[2], char *url, const char *prog, int flags);
-extern int finish_connect(pid_t pid);
+extern struct child_process *git_connect(int fd[2], char *url, const char *prog, int flags);
+extern int finish_connect(struct child_process *chld);
extern int path_match(const char *path, int nr, char **match);
extern int get_ack(int fd, unsigned char *result_sha1);
extern struct ref **get_remote_heads(int in, struct ref **list, int nr_match, char **match, unsigned int flags);
diff --git a/connect.c b/connect.c
index 3d5c4ab..f6dcab9 100644
--- a/connect.c
+++ b/connect.c
@@ -468,21 +468,22 @@ char *get_port(char *host)
}
/*
- * This returns 0 if the transport protocol does not need fork(2),
+ * This returns NULL if the transport protocol does not need fork(2),
* or a process id if it does. Once done, finish the connection
* with finish_connect() with the value returned from this function
- * (it is safe to call finish_connect() with 0 to support the former
+ * (it is safe to call finish_connect() with NULL to support the former
* case).
*
- * Does not return a negative value on error; it just dies.
+ * If it returns, the connect is successful; it just dies on errors.
*/
-pid_t git_connect(int fd[2], char *url, const char *prog, int flags)
+struct child_process *git_connect(int fd[2], char *url,
+ const char *prog, int flags)
{
char *host, *path = url;
char *end;
int c;
int pipefd[2][2];
- pid_t pid;
+ struct child_process *chld;
enum protocol protocol = PROTO_LOCAL;
int free_path = 0;
char *port = NULL;
@@ -568,15 +569,16 @@ pid_t git_connect(int fd[2], char *url, const char *prog, int flags)
free(target_host);
if (free_path)
free(path);
- return 0;
+ return NULL;
}
if (pipe(pipefd[0]) < 0 || pipe(pipefd[1]) < 0)
die("unable to create pipe pair for communication");
- pid = fork();
- if (pid < 0)
+ chld = xcalloc(1, sizeof(*chld));
+ chld->pid = fork();
+ if (chld->pid < 0)
die("unable to fork");
- if (!pid) {
+ if (!chld->pid) {
struct strbuf cmd;
strbuf_init(&cmd, MAX_CMD_LEN);
@@ -625,15 +627,15 @@ pid_t git_connect(int fd[2], char *url, const char *prog, int flags)
close(pipefd[1][0]);
if (free_path)
free(path);
- return pid;
+ return chld;
}
-int finish_connect(pid_t pid)
+int finish_connect(struct child_process *chld)
{
- if (pid == 0)
+ if (chld == NULL)
return 0;
- while (waitpid(pid, NULL, 0) < 0) {
+ while (waitpid(chld->pid, NULL, 0) < 0) {
if (errno != EINTR)
return -1;
}
diff --git a/peek-remote.c b/peek-remote.c
index ceb7871..59cc8eb 100644
--- a/peek-remote.c
+++ b/peek-remote.c
@@ -25,7 +25,7 @@ int main(int argc, char **argv)
int i, ret;
char *dest = NULL;
int fd[2];
- pid_t pid;
+ struct child_process *chld;
int nongit = 0;
unsigned flags = 0;
@@ -64,12 +64,10 @@ int main(int argc, char **argv)
if (!dest || i != argc - 1)
usage(peek_remote_usage);
- pid = git_connect(fd, dest, uploadpack, 0);
- if (pid < 0)
- return 1;
+ chld = git_connect(fd, dest, uploadpack, 0);
ret = peek_remote(fd, flags);
close(fd[0]);
close(fd[1]);
- ret |= finish_connect(pid);
+ ret |= finish_connect(chld);
return !!ret;
}
diff --git a/send-pack.c b/send-pack.c
index 4533d1b..e9257fd 100644
--- a/send-pack.c
+++ b/send-pack.c
@@ -362,7 +362,7 @@ int main(int argc, char **argv)
char *dest = NULL;
char **heads = NULL;
int fd[2], ret;
- pid_t pid;
+ struct child_process *chld;
char *remote_name = NULL;
struct remote *remote = NULL;
@@ -426,12 +426,10 @@ int main(int argc, char **argv)
}
}
- pid = git_connect(fd, dest, receivepack, verbose ? CONNECT_VERBOSE : 0);
- if (pid < 0)
- return 1;
+ chld = git_connect(fd, dest, receivepack, verbose ? CONNECT_VERBOSE : 0);
ret = send_pack(fd[0], fd[1], remote, nr_heads, heads);
close(fd[0]);
close(fd[1]);
- ret |= finish_connect(pid);
+ ret |= finish_connect(chld);
return !!ret;
}
diff --git a/transport.c b/transport.c
index 3475cca..54ed9bc 100644
--- a/transport.c
+++ b/transport.c
@@ -279,18 +279,13 @@ static struct ref *get_refs_via_connect(const struct transport *transport)
struct git_transport_data *data = transport->data;
struct ref *refs;
int fd[2];
- pid_t pid;
char *dest = xstrdup(transport->url);
-
- pid = git_connect(fd, dest, data->uploadpack, 0);
-
- if (pid < 0)
- die("Failed to connect to \"%s\"", transport->url);
+ struct child_process *chld = git_connect(fd, dest, data->uploadpack, 0);
get_remote_heads(fd[0], &refs, 0, NULL, 0);
packet_flush(fd[1]);
- finish_connect(pid);
+ finish_connect(chld);
free(dest);
--
1.5.3.3.1134.gee562
^ permalink raw reply related
* [PATCH 4/5] Use run_command() to spawn external diff programs instead of fork/exec.
From: Johannes Sixt @ 2007-09-30 20:10 UTC (permalink / raw)
To: gitster; +Cc: git, Johannes Sixt
In-Reply-To: <1191183001-5368-4-git-send-email-johannes.sixt@telecom.at>
Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
---
diff.c | 38 +++-----------------------------------
1 files changed, 3 insertions(+), 35 deletions(-)
diff --git a/diff.c b/diff.c
index 0bd7e24..29dfa82 100644
--- a/diff.c
+++ b/diff.c
@@ -9,6 +9,7 @@
#include "xdiff-interface.h"
#include "color.h"
#include "attr.h"
+#include "run-command.h"
#ifdef NO_FAST_WORKING_DIRECTORY
#define FAST_WORKING_DIRECTORY 0
@@ -1748,40 +1749,6 @@ static void remove_tempfile_on_signal(int signo)
raise(signo);
}
-static int spawn_prog(const char *pgm, const char **arg)
-{
- pid_t pid;
- int status;
-
- fflush(NULL);
- pid = fork();
- if (pid < 0)
- die("unable to fork");
- if (!pid) {
- execvp(pgm, (char *const*) arg);
- exit(255);
- }
-
- while (waitpid(pid, &status, 0) < 0) {
- if (errno == EINTR)
- continue;
- return -1;
- }
-
- /* Earlier we did not check the exit status because
- * diff exits non-zero if files are different, and
- * we are not interested in knowing that. It was a
- * mistake which made it harder to quit a diff-*
- * session that uses the git-apply-patch-script as
- * the GIT_EXTERNAL_DIFF. A custom GIT_EXTERNAL_DIFF
- * should also exit non-zero only when it wants to
- * abort the entire diff-* session.
- */
- if (WIFEXITED(status) && !WEXITSTATUS(status))
- return 0;
- return -1;
-}
-
/* An external diff command takes:
*
* diff-cmd name infile1 infile1-sha1 infile1-mode \
@@ -1834,7 +1801,8 @@ static void run_external_diff(const char *pgm,
*arg++ = name;
}
*arg = NULL;
- retval = spawn_prog(pgm, spawn_arg);
+ fflush(NULL);
+ retval = run_command_v_opt(spawn_arg, 0);
remove_tempfile();
if (retval) {
fprintf(stderr, "external diff died, stopping at %s.\n", name);
--
1.5.3.3.1134.gee562
^ permalink raw reply related
* [PATCH 2/5] Use start_command() in git_connect() instead of explicit fork/exec.
From: Johannes Sixt @ 2007-09-30 20:09 UTC (permalink / raw)
To: gitster; +Cc: git, Johannes Sixt
In-Reply-To: <1191183001-5368-2-git-send-email-johannes.sixt@telecom.at>
The child process handling is delegated to start_command() and
finish_command().
Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
---
connect.c | 104 ++++++++++++++++++++++++++++--------------------------------
1 files changed, 49 insertions(+), 55 deletions(-)
diff --git a/connect.c b/connect.c
index f6dcab9..29fd431 100644
--- a/connect.c
+++ b/connect.c
@@ -482,11 +482,12 @@ struct child_process *git_connect(int fd[2], char *url,
char *host, *path = url;
char *end;
int c;
- int pipefd[2][2];
struct child_process *chld;
enum protocol protocol = PROTO_LOCAL;
int free_path = 0;
char *port = NULL;
+ const char **arg;
+ struct strbuf cmd;
/* Without this we cannot rely on waitpid() to tell
* what happened to our children.
@@ -572,72 +573,65 @@ struct child_process *git_connect(int fd[2], char *url,
return NULL;
}
- if (pipe(pipefd[0]) < 0 || pipe(pipefd[1]) < 0)
- die("unable to create pipe pair for communication");
chld = xcalloc(1, sizeof(*chld));
- chld->pid = fork();
- if (chld->pid < 0)
- die("unable to fork");
- if (!chld->pid) {
- struct strbuf cmd;
-
- strbuf_init(&cmd, MAX_CMD_LEN);
- strbuf_addstr(&cmd, prog);
- strbuf_addch(&cmd, ' ');
- sq_quote_buf(&cmd, path);
- if (cmd.len >= MAX_CMD_LEN)
- die("command line too long");
-
- dup2(pipefd[1][0], 0);
- dup2(pipefd[0][1], 1);
- close(pipefd[0][0]);
- close(pipefd[0][1]);
- close(pipefd[1][0]);
- close(pipefd[1][1]);
- if (protocol == PROTO_SSH) {
- const char *ssh, *ssh_basename;
- ssh = getenv("GIT_SSH");
- if (!ssh) ssh = "ssh";
- ssh_basename = strrchr(ssh, '/');
- if (!ssh_basename)
- ssh_basename = ssh;
- else
- ssh_basename++;
- if (!port)
- execlp(ssh, ssh_basename, host, cmd.buf, NULL);
- else
- execlp(ssh, ssh_basename, "-p", port, host,
- cmd.buf, NULL);
+ strbuf_init(&cmd, MAX_CMD_LEN);
+ strbuf_addstr(&cmd, prog);
+ strbuf_addch(&cmd, ' ');
+ sq_quote_buf(&cmd, path);
+ if (cmd.len >= MAX_CMD_LEN)
+ die("command line too long");
+
+ chld->in = chld->out = -1;
+ chld->argv = arg = xcalloc(6, sizeof(*arg));
+ if (protocol == PROTO_SSH) {
+ const char *ssh = getenv("GIT_SSH");
+ if (!ssh) ssh = "ssh";
+
+ *arg++ = ssh;
+ if (port) {
+ *arg++ = "-p";
+ *arg++ = port;
}
- else {
- unsetenv(ALTERNATE_DB_ENVIRONMENT);
- unsetenv(DB_ENVIRONMENT);
- unsetenv(GIT_DIR_ENVIRONMENT);
- unsetenv(GIT_WORK_TREE_ENVIRONMENT);
- unsetenv(GRAFT_ENVIRONMENT);
- unsetenv(INDEX_ENVIRONMENT);
- execlp("sh", "sh", "-c", cmd.buf, NULL);
- }
- die("exec failed");
+ *arg++ = host;
+ }
+ else {
+ /* remove these from the environment */
+ const char *env[] = {
+ ALTERNATE_DB_ENVIRONMENT,
+ DB_ENVIRONMENT,
+ GIT_DIR_ENVIRONMENT,
+ GIT_WORK_TREE_ENVIRONMENT,
+ GRAFT_ENVIRONMENT,
+ INDEX_ENVIRONMENT,
+ NULL
+ };
+ chld->env = env;
+ *arg++ = "sh";
+ *arg++ = "-c";
}
- fd[0] = pipefd[0][0];
- fd[1] = pipefd[1][1];
- close(pipefd[0][1]);
- close(pipefd[1][0]);
+ *arg++ = cmd.buf;
+ *arg = NULL;
+
+ if (start_command(chld))
+ die("unable to fork");
+
+ fd[0] = chld->out; /* read from child's stdout */
+ fd[1] = chld->in; /* write to child's stdin */
if (free_path)
free(path);
+ strbuf_release(&cmd);
return chld;
}
int finish_connect(struct child_process *chld)
{
+ int code;
if (chld == NULL)
return 0;
- while (waitpid(chld->pid, NULL, 0) < 0) {
- if (errno != EINTR)
- return -1;
- }
- return 0;
+ code = finish_command(chld);
+ free(chld->argv);
+ free(chld);
+ return code;
}
--
1.5.3.3.1134.gee562
^ permalink raw reply related
* [PATCH 3/5] Use start_command() to run the filter instead of explicit fork/exec.
From: Johannes Sixt @ 2007-09-30 20:09 UTC (permalink / raw)
To: gitster; +Cc: git, Johannes Sixt
In-Reply-To: <1191183001-5368-3-git-send-email-johannes.sixt@telecom.at>
Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
---
convert.c | 36 ++++++++++--------------------------
1 files changed, 10 insertions(+), 26 deletions(-)
diff --git a/convert.c b/convert.c
index 0d5e909..560679d 100644
--- a/convert.c
+++ b/convert.c
@@ -196,40 +196,24 @@ static int filter_buffer(const char *path, const char *src,
/*
* Spawn cmd and feed the buffer contents through its stdin.
*/
- struct child_process child_process;
- int pipe_feed[2];
+ struct child_process chld;
int write_err, status;
+ const char *argv[] = { "sh", "-c", cmd, NULL };
- memset(&child_process, 0, sizeof(child_process));
+ memset(&chld, 0, sizeof(chld));
+ chld.argv = argv;
+ chld.in = -1;
- if (pipe(pipe_feed) < 0) {
- error("cannot create pipe to run external filter %s", cmd);
- return 1;
- }
+ if (start_command(&chld))
+ return error("cannot fork to run external filter %s", cmd);
- child_process.pid = fork();
- if (child_process.pid < 0) {
- error("cannot fork to run external filter %s", cmd);
- close(pipe_feed[0]);
- close(pipe_feed[1]);
- return 1;
- }
- if (!child_process.pid) {
- dup2(pipe_feed[0], 0);
- close(pipe_feed[0]);
- close(pipe_feed[1]);
- execlp("sh", "sh", "-c", cmd, NULL);
- return 1;
- }
- close(pipe_feed[0]);
-
- write_err = (write_in_full(pipe_feed[1], src, size) < 0);
- if (close(pipe_feed[1]))
+ write_err = (write_in_full(chld.in, src, size) < 0);
+ if (close(chld.in))
write_err = 1;
if (write_err)
error("cannot feed the input to external filter %s", cmd);
- status = finish_command(&child_process);
+ status = finish_command(&chld);
if (status)
error("external filter %s failed %d", cmd, -status);
return (write_err || status);
--
1.5.3.3.1134.gee562
^ permalink raw reply related
* [PATCH 0/5] fork/exec removal series
From: Johannes Sixt @ 2007-09-30 20:09 UTC (permalink / raw)
To: gitster; +Cc: git, Johannes Sixt
Here is a series of patches that removes a number fork/exec pairs.
They are replaced by delegating to start_command/finish_command/run_command.
You can regard this as the beginning of the MinGW port integration.
There still remain a few forks, which fall into these categories:
- They are in tools or code that are not (yet) ported to MinGW.[*]
- The fork()s are not followed by exec(). These need a different
implementation. I am thinking of a start_coroutine()/finish_coroutine()
API that is implemented with threads in MinGW. (Suggestions of a better
as well as implementations are welcome.)
- The upload-pack case calls for an entirely different solution.
[*] Just this weekend Mike Pape ported git-daemon, but I didn't find the
time to have it integrated in this series - if that were possible at all.
Patch 2 depends on Patch 1; otherwise, there are no dependencies.
The series goes on top of next (it touches str_buf stuff in connect.c).
builtin-archive.c | 8 +--
builtin-fetch-pack.c | 63 ++++++++-----------------
cache.h | 4 +-
connect.c | 126 ++++++++++++++++++++++++--------------------------
convert.c | 36 ++++----------
diff.c | 38 +--------------
peek-remote.c | 8 +--
send-pack.c | 8 +--
transport.c | 9 +---
9 files changed, 106 insertions(+), 194 deletions(-)
-- Hannes
^ permalink raw reply
* Re: suggestion for git stash
From: Junio C Hamano @ 2007-09-30 19:59 UTC (permalink / raw)
To: Bruno Haible; +Cc: git
In-Reply-To: <200709302050.41273.bruno@clisp.org>
Isn't "stash apply --index" what you talk about?
^ permalink raw reply
* Re: GIT_EXTERNAL_DIFF invoked with undocumented calling convention after unstashing conflicts
From: Junio C Hamano @ 2007-09-30 19:59 UTC (permalink / raw)
To: Bruno Haible; +Cc: git
In-Reply-To: <200709302117.37422.bruno@clisp.org>
> "git diff --uncached" invokes the GIT_EXTERNAL_DIFF variable with just one
> argument (instead of 7 arguments, as documented) in a particular situation:
You are looking at an unmerged path.
'GIT_EXTERNAL_DIFF'::
When the environment variable 'GIT_EXTERNAL_DIFF' is set, the
program named by it is called, instead of the diff invocation
described above. For a path that is added, removed, or modified,
'GIT_EXTERNAL_DIFF' is called with 7 parameters:
...
+
For a path that is unmerged, 'GIT_EXTERNAL_DIFF' is called with 1
parameter, <path>.
The script needs to decide how it wants to present an unmerged
path; the information on each unmerged stages can be read from
the output of "ls-files -u $thatpath".
^ permalink raw reply
* GIT_EXTERNAL_DIFF ignored after unstashing conflicts
From: Bruno Haible @ 2007-09-30 19:18 UTC (permalink / raw)
To: git
[-- Attachment #1: Type: text/plain, Size: 1014 bytes --]
Hi,
"git diff" ignores the GIT_EXTERNAL_DIFF variable in a particular situation:
when there are conflicts after "git stash apply".
To reproduce:
- Set environment variable GIT_EXTERNAL_DIFF to point to the attached
script.
- Make a clean gnulib checkout, 1 day old.
- Add a entry to the top of the ChangeLog.
- $ git pull
fails due a conflict.
- $ git stash
- $ git pull
- $ git stash apply
- $ git-diff | cat
yields:
diff --cc ChangeLog
index 443ad76,991c26b..0000000
--- a/ChangeLog
+++ b/ChangeLog
@@@ -1,7 -1,6 +1,11 @@@
2007-09-30 Bruno Haible <bruno@clisp.org>
++<<<<<<< Updated upstream:ChangeLog
+ * tests/test-getaddrinfo.c (AF_UNSPEC): Provide a fallback definition.
+ Needed on BeOS.
++=======
+ * Some other changes.
++>>>>>>> Stashed changes:ChangeLog
2007-09-30 Bruno Haible <bruno@clisp.org>
The script has not been called (witness: the echo command at its line 2).
Can it be called, like in the case of "git-diff --cached"?
Bruno
[-- Attachment #2: my-diff-for-git --]
[-- Type: application/x-shellscript, Size: 981 bytes --]
^ permalink raw reply
* GIT_EXTERNAL_DIFF invoked with undocumented calling convention after unstashing conflicts
From: Bruno Haible @ 2007-09-30 19:17 UTC (permalink / raw)
To: git
[-- Attachment #1: Type: text/plain, Size: 1338 bytes --]
Hi,
"git diff --uncached" invokes the GIT_EXTERNAL_DIFF variable with just one
argument (instead of 7 arguments, as documented) in a particular situation:
when there are conflicts after "git stash apply".
To reproduce:
- Set environment variable GIT_EXTERNAL_DIFF to point to the attached
script.
- Make a clean gnulib checkout, 1 day old.
- Add a entry to the top of the ChangeLog.
- $ git pull
fails due a conflict.
- $ git stash
- $ git pull
- $ git stash apply
- $ git-diff --cached | cat
yields:
my-diff-for-git ChangeLog
diff --cc ChangeLog
index 443ad76,991c26b..0000000
--- a/ChangeLog
+++ b/ChangeLog
@@@ -1,7 -1,6 +1,11 @@@
2007-09-30 Bruno Haible <bruno@clisp.org>
++<<<<<<< Updated upstream:ChangeLog
+ * tests/test-getaddrinfo.c (AF_UNSPEC): Provide a fallback definition.
+ Needed on BeOS.
++=======
+ * Some other changes.
++>>>>>>> Stashed changes:ChangeLog
2007-09-30 Bruno Haible <bruno@clisp.org>
As you can see from the output of the script's line 2, it was called with
just one argument. This is not enough information for producing output
in a different way than the built-in way - defeating the purpose of
GIT_EXTERNAL_DIFF.
Can the GIT_EXTERNAL_DIFF invocation be done with 7 or more arguments?
It'd be OK to extend the calling convention.
Bruno
[-- Attachment #2: my-diff-for-git --]
[-- Type: application/x-shellscript, Size: 981 bytes --]
^ permalink raw reply
* [NEWS] git adapter included in upcoming Capistrano 2.1
From: Geoffrey Grosenbach @ 2007-09-30 19:13 UTC (permalink / raw)
To: git
I just received news that a git adapter will be included in the next
release of the Ruby-based Capistrano webapp deployment system.
http://dev.rubyonrails.org/ticket/9635
http://capify.org/
I'm using the patch right now and it works well. If you use
Capistrano, you now have one more reason to switch to git!
--
Geoffrey Grosenbach
http://peepcode.com
^ permalink raw reply
* suggestion for git stash
From: Bruno Haible @ 2007-09-30 18:50 UTC (permalink / raw)
To: git
Hi,
"git stash" has the effect of losing the distinction between untracked
changes and changes in the index.
To reproduce:
- Clone the gnulib repository or of any repository with at least 2 files.
- Make changes to two files, say, README and NEWS.
$ git add README
- $ git status
now reports:
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: README
#
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
#
# modified: NEWS
#
- $ git stash
- $ git stash apply
- $ git status
now reports:
# On branch master
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
#
# modified: NEWS
# modified: README
#
no changes added to commit (use "git add" and/or "git commit -a")
Could "git stash" be changed to memorize which changes were already
scheduled for commit and which didn't?
Bruno
^ permalink raw reply
* [PATCH] Support tags in uncommit - use git_id instead of rev_parse
From: Pavel Roskin @ 2007-09-30 17:26 UTC (permalink / raw)
To: Catalin Marinas, git
Signed-off-by: Pavel Roskin <proski@gnu.org>
---
stgit/commands/uncommit.py | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/stgit/commands/uncommit.py b/stgit/commands/uncommit.py
index 0cd0fb0..c22d3ea 100644
--- a/stgit/commands/uncommit.py
+++ b/stgit/commands/uncommit.py
@@ -65,7 +65,7 @@ def func(parser, options, args):
if len(args) != 0:
parser.error('cannot specify patch name with --to')
patch_nr = patchnames = None
- to_commit = git.rev_parse(options.to)
+ to_commit = git_id(options.to)
elif options.number:
if options.number <= 0:
parser.error('invalid value passed to --number')
^ permalink raw reply related
* [PATCH] rebase: add --signoff option
From: Steffen Prohaska @ 2007-09-30 16:15 UTC (permalink / raw)
To: git; +Cc: Steffen Prohaska
When preparing a series of commits for upstream you may
need to signoff commits if you forgot to do so earlier.
This patch teaches git-rebase to signoff during rebase
if you pass the option --signoff.
Notes
1) --signoff cannot be used simultaneously with --interactive.
2) --signoff forces a rebase even if current path is a
descendant of <upstream>.
Signed-off-by: Steffen Prohaska <prohaska@zib.de>
---
Documentation/git-rebase.txt | 9 +++++++--
git-rebase--interactive.sh | 3 +++
git-rebase.sh | 10 ++++++++--
3 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index e8e7579..befe337 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -8,8 +8,8 @@ git-rebase - Forward-port local commits to the updated upstream head
SYNOPSIS
--------
[verse]
-'git-rebase' [-i | --interactive] [-v | --verbose] [-m | --merge]
- [-C<n>] [ --whitespace=<option>] [-p | --preserve-merges]
+'git-rebase' [-i | --interactive] [-v | --verbose] [-m | --merge] [-C<n>]
+ [--signoff] [ --whitespace=<option>] [-p | --preserve-merges]
[--onto <newbase>] <upstream> [<branch>]
'git-rebase' --continue | --skip | --abort
@@ -201,6 +201,11 @@ OPTIONS
is used instead (`git-merge-recursive` when merging a single
head, `git-merge-octopus` otherwise). This implies --merge.
+--signoff::
+ Add `Signed-off-by:` line to each commit message, using
+ the committer identity of yourself.
+
+
-v, \--verbose::
Display a diffstat of what changed upstream since the last rebase.
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 8568a4f..29cef17 100755
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -395,6 +395,9 @@ do
-C*)
die "Interactive rebase uses merge, so $1 does not make sense"
;;
+ --si|--sig|--sign|--signo|--signof|--signoff)
+ die "Interactive rebase doesn't support simultaneous signoff."
+ ;;
-v|--verbose)
VERBOSE=t
;;
diff --git a/git-rebase.sh b/git-rebase.sh
index 1583402..3b06bf4 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -46,6 +46,7 @@ dotest=$GIT_DIR/.dotest-merge
prec=4
verbose=
git_am_opt=
+opt_signoff=
continue_merge () {
test -n "$prev_head" || die "prev_head must be defined"
@@ -200,7 +201,7 @@ do
;;
-s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\
--strateg=*|--strategy=*|\
- -s|--s|--st|--str|--stra|--strat|--strate|--strateg|--strategy)
+ -s|--st|--str|--stra|--strat|--strate|--strateg|--strategy)
case "$#,$1" in
*,*=*)
strategy=`expr "z$1" : 'z-[^=]*=\(.*\)'` ;;
@@ -221,6 +222,10 @@ do
-C*)
git_am_opt="$git_am_opt $1"
;;
+ --si|--sig|--sign|--signo|--signof|--signoff)
+ git_am_opt="$git_am_opt --signoff"
+ opt_signoff=t
+ ;;
-*)
usage
;;
@@ -302,8 +307,9 @@ branch=$(git rev-parse --verify "${branch_name}^0") || exit
# Check if we are already based on $onto with linear history,
# but this should be done only when upstream and onto are the same.
+# The check must also be skipped if signoff is requested.
mb=$(git merge-base "$onto" "$branch")
-if test "$upstream" = "$onto" && test "$mb" = "$onto" &&
+if test "$upstream" = "$onto" && test "$mb" = "$onto" && test -z "$opt_signoff" &&
# linear history?
! git rev-list --parents "$onto".."$branch" | grep " .* " > /dev/null
then
--
1.5.3.3.127.g40d17
^ permalink raw reply related
* Re: A tour of git: the basics (and notes on some unfriendly messages)
From: Wincent Colaiuta @ 2007-09-30 14:31 UTC (permalink / raw)
To: Pierre Habouzit; +Cc: Shawn O. Pearce, Carl Worth, git
In-Reply-To: <20070930134937.GG22560@artemis.corp>
El 30/9/2007, a las 15:49, Pierre Habouzit escribió:
> On Sun, Sep 30, 2007 at 12:45:34PM +0000, Wincent Colaiuta wrote:
>>
>> I think that most people just want to know, "Did it work or not?"
>> and so
>> when the commands chatter too much they go into filter mode, don't
>> really
>> read the output, let alone try to understand it, and just skim it.
>> Ideally Git would be much less "chattery" in general when things
>> work,
>> and only be more verbose when things go wrong; of course, finding
>> that
>> balance point is where the art lies.
>
> That's true for git merge that is fast. But people also want to know
> the command is not stuck in an infinite loop, and for that progress
> bars
> or little \|/- animation.
Yes, I agree. I probably should have said that they either want to
know "*Did* it work?" for near-instant operations (most Git
operations, hopefully), and "*Is* it working?" for long-running ones
(network ops, for example) and in those cases you're right that a
progress bar would be a nice enhancement.
Cheers,
Wincent
^ permalink raw reply
* Re: git-svn merge helper
From: Benoit SIGOURE @ 2007-09-30 14:15 UTC (permalink / raw)
To: Björn Steinbrink; +Cc: git
In-Reply-To: <20070930110550.GA4557@atjola.homenet>
[-- Attachment #1: Type: text/plain, Size: 1271 bytes --]
On Sep 30, 2007, at 1:05 PM, Björn Steinbrink wrote:
> Hi,
>
> I recently discovered git-svn and absolutey love it. One thing that
> I'm
> missing though, is an equivalent of "svn merge" for merging between
> svn
> remotes, to support the SVN way of using "squashed" merges, where you
> just note the merge meta-data in the commit message. "git merge"
> didn't
> work for me (and probably isn't expected to work) to merge between two
> svn branches, so I've resorted to cherry-picking the required commits
> one by one into a temporary branch and then squashing them together by
> doing a --squash merge with a second temporary branch (as in [1]).
I fail to see why you'd want to reproduce the broken behavior of svn
merge. Anyways, git-svn is a great way to merge SVN branches,
unfortunately it can't detect when merges happened on the SVN side.
I think you can use it nevertheless by manually adding a graft at the
last merge point, which would help you merging the right revisions
without having to specify what needs to be merged (unless someone
made another merge on the SVN side, in which case you need to update
your graft).
Cheers,
--
Benoit Sigoure aka Tsuna
EPITA Research and Development Laboratory
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 186 bytes --]
^ permalink raw reply
* Re: Obliterating a commit
From: Wincent Colaiuta @ 2007-09-30 14:13 UTC (permalink / raw)
To: Matthias Kestenholz; +Cc: Git Mailing List
In-Reply-To: <1f6632e50709300515h57f4b4ffh9a18fef29b134f13@mail.gmail.com>
El 30/9/2007, a las 14:15, Matthias Kestenholz escribió:
> If you use ssh to push your changes (that is, you are not copying
> or rsyncing packfiles), only commits, trees and blobs, which are
> reachable
> through the DAG will be published. Commits and Blobs which are only
> reachable through your reflog are not published, since the reflog
> only applies
> to your local repository.
Ah, this is good to know. Yes, I do principally publish by pushing to
a central repo, but I wanted to really destroy the objects just in
case in the future I or somebody else ever clones my local repo.
> The simplest thing you could do is remove the reflog for HEAD and
> refs/heads/master respectively your current branch and run 'git prune'
> afterwards (if you have not repacked
> already, otherwise you'd need to run 'git repack -a -d' or 'git gc'
> to get
> rid of blobs inside your packfile.
Thanks very much, Matthias. Blowing away those reflogs and running
git-prune worked and it's doesn't require too much fiddling.
Cheers,
Wincent
^ permalink raw reply
* Re: A tour of git: the basics (and notes on some unfriendly messages)
From: Pierre Habouzit @ 2007-09-30 13:49 UTC (permalink / raw)
To: Wincent Colaiuta; +Cc: Shawn O. Pearce, Carl Worth, git
In-Reply-To: <912CB4AE-83B9-42D7-A591-E721D1E22439@wincent.com>
[-- Attachment #1: Type: text/plain, Size: 1608 bytes --]
On Sun, Sep 30, 2007 at 12:45:34PM +0000, Wincent Colaiuta wrote:
> El 29/9/2007, a las 11:01, Pierre Habouzit escribió:
>
> > Many git commands output are still messy and indeed, having them in C
> >should help in that regard. The usual culprit are I think:
> >
> > * git fetch/clone/pull/.. ;
> > * git push ;
> > * git repack/gc/... ;
> > * git merge (even with the merge.verbosity set to the minimum it's
> > still not very readable and confusing).
> >
> >
> > I do believe that the quite verbose output git commands sometimes have
> >is quite confusing, and let the user think it's messy. I believe that
> >porcelains should be more silent, it's OK for the plumbing to spit
> >progress messages and so on, because people using the plumbing are able
> >to understand those, but porcelains should not.
>
> I think that most people just want to know, "Did it work or not?" and so
> when the commands chatter too much they go into filter mode, don't really
> read the output, let alone try to understand it, and just skim it.
> Ideally Git would be much less "chattery" in general when things work,
> and only be more verbose when things go wrong; of course, finding that
> balance point is where the art lies.
That's true for git merge that is fast. But people also want to know
the command is not stuck in an infinite loop, and for that progress bars
or little \|/- animation.
--
·O· Pierre Habouzit
··O madcoder@debian.org
OOO http://www.madism.org
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: A tour of git: the basics (and notes on some unfriendly messages)
From: Steffen Prohaska @ 2007-09-30 13:41 UTC (permalink / raw)
To: Johannes Schindelin
Cc: Junio C Hamano, Git Mailing List, Carl Worth, Shawn O. Pearce
In-Reply-To: <Pine.LNX.4.64.0709301343000.28395@racer.site>
On Sep 30, 2007, at 2:44 PM, Johannes Schindelin wrote:
>>
>> A much simpler output could be easier to scan by a human
>>
>> updating 'refs/heads/master' .. fast forward .. ok.
>> updating 'refs/heads/pu' .. forced non-fast forward .. ok.
>> updating 'refs/heads/next' ..
>> ERROR: 'refs/heads/next' not updating to non-fast forward
>> exit(1) here.
>
> No, please no. This is way too short.
>
> If at all, please let 8c3275abcacb83ea3f4c4f4ceb2376799fc282bd be an
> example, and make git respect several different output levels, but not
> changing the default (at first).
good idea.
Steffen
^ permalink raw reply
* Re: Stashing untracked files
From: Wincent Colaiuta @ 2007-09-30 13:18 UTC (permalink / raw)
To: Neil Macneale; +Cc: git, Johannes Schindelin
In-Reply-To: <46FF1F1E.2050000@theory.org>
El 30/9/2007, a las 5:59, Neil Macneale escribió:
> $ git stash -u # stash everything, even untracked files. I never
> # suggesting modifying the default behavior.
Provided it's not the default behaviour, and provided that it doesn't
add ignored files, this sounds perfectly reasonable and potentially
quite useful.
I say *potentially* only because I've yet to find a situation wherein
I can't just do the following:
<hack> # lots of untracked files floating around
$ git stash # untracked files stay exactly where they were
<orthogonal hacking> # untracked files still there
$ git stash apply # still there...
<hack> # still there...
If the content of the untracked files is both, (a) important and (b)
being modified over time, then perhaps it should be being tracked.
Wincent
^ permalink raw reply
* Re: [PATCH v3 2/2] fetch/push: readd rsync support
From: Johannes Schindelin @ 2007-09-30 12:58 UTC (permalink / raw)
To: Junio C Hamano; +Cc: spearce, Daniel Barkalow, git
In-Reply-To: <7vhclciszz.fsf@gitster.siamese.dyndns.org>
Hi,
On Sat, 29 Sep 2007, Junio C Hamano wrote:
> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
>
> > We lost rsync support when transitioning from shell to C. Support it
> > again (even if the transport is technically deprecated, some people just
> > do not have any chance to use anything else).
>
> s/chance/choice/?
Hehe. I did mean it like that, but feel free to edit!
> > +test "$TEST_RSYNC" && {
>
> Somehow this feels dirty ... perhaps leave early like:
>
> if test -z "$TEST_RSYNC"
> then
> test_expect_success 'skipping rsync transport tests' :
> test_done
> exit
> fi
Okay.
> > diff --git a/transport.c b/transport.c
> > index 4f9cddc..a2ee8f3 100644
> > --- a/transport.c
> > +++ b/transport.c
> > @@ -6,6 +6,330 @@
> > ...
> > +{
> > + struct strbuf buf = STRBUF_INIT, temp_dir = STRBUF_INIT;
> > + struct ref dummy, *tail = &dummy;
> > + struct child_process rsync;
> > + const char *args[5];
> > + int temp_dir_len;
> > +
> > + /* copy the refs to the temporary directory */
> > +
> > + strbuf_addstr(&temp_dir, git_path("rsync-refs-XXXXXX"));
> > + if (!mkdtemp(temp_dir.buf))
> > + die ("Could not make temporary directory");
>
> I wonder how portable mkdtemp() is (it does not seem to be POSIX);
> would we need something in compat/ perhaps based on tempnam()?
My man page said BSD, so I did not bother any more...
Besides, using "tmpnam()" makes gcc say that it is dangerous, and I should
use mkstemp() instead...
> > +static int fetch_objs_via_rsync(struct transport *transport,
> > + int nr_objs, struct ref **to_fetch)
> > +{
> > + struct strbuf buf = STRBUF_INIT;
> > + struct child_process rsync;
> > + const char *args[8];
> > + int result;
> > +
> > + strbuf_addstr(&buf, transport->url);
> > + strbuf_addstr(&buf, "/objects/");
> > +
> > + memset(&rsync, 0, sizeof(rsync));
> > + rsync.argv = args;
> > + rsync.stdout_to_stderr = 1;
> > + args[0] = "rsync";
> > + args[1] = transport->verbose ? "-rv" : "-r";
> > + args[2] = "--ignore-existing";
> > + args[3] = "--exclude";
> > + args[4] = "info";
> > + args[5] = buf.buf;
> > + args[6] = get_object_directory();
> > + args[7] = NULL;
>
> Hmm, we used to do "rsync $remote/objects/ $our/.git/objects/", but this
> omits the trailing "/" from our side. I suspect the reason was to deal
> with the case where our .git/objects was a symlink to elsewhere (which
> was how you did alternates before alternates was invented), which may
> not matter anymore these days.
Nevertheless, this was an oversight on my side. Will change to use a
second strbuf for the local objects directory.
^ permalink raw reply
* Re: A tour of git: the basics (and notes on some unfriendly messages)
From: Johannes Schindelin @ 2007-09-30 12:44 UTC (permalink / raw)
To: Steffen Prohaska
Cc: Junio C Hamano, Git Mailing List, Carl Worth, Shawn O. Pearce
In-Reply-To: <E8851B12-AAA5-4B4D-9F28-C5AB5AEF0E57@zib.de>
Hi,
On Sun, 30 Sep 2007, Steffen Prohaska wrote:
>
> On Sep 30, 2007, at 12:25 AM, Junio C Hamano wrote:
>
> > Steffen Prohaska <prohaska@zib.de> writes:
> >
> > > - git push: prints updates of remote heads. A message about
> > > failing to update a remote head may get lost.
> >
> > Please do not remove the report of successful update, as people often
> > say "git push" or "git push $there" without explicitly saying which
> > refs to push. When pushing out to publish, I say "git push ko" (to
> > mean k.org) and I _want_ my positive feedback.
>
> Yes but it's pretty technical.
>
> A much simpler output could be easier to scan by a human
>
> updating 'refs/heads/master' .. fast forward .. ok.
> updating 'refs/heads/pu' .. forced non-fast forward .. ok.
> updating 'refs/heads/next' ..
> ERROR: 'refs/heads/next' not updating to non-fast forward
> exit(1) here.
No, please no. This is way too short.
If at all, please let 8c3275abcacb83ea3f4c4f4ceb2376799fc282bd be an
example, and make git respect several different output levels, but not
changing the default (at first).
Ciao,
Dscho
^ permalink raw reply
* Re: A tour of git: the basics (and notes on some unfriendly messages)
From: Wincent Colaiuta @ 2007-09-30 12:45 UTC (permalink / raw)
To: Pierre Habouzit; +Cc: Shawn O. Pearce, Carl Worth, git
In-Reply-To: <20070929090121.GA4216@artemis.corp>
El 29/9/2007, a las 11:01, Pierre Habouzit escribió:
> Many git commands output are still messy and indeed, having them
> in C
> should help in that regard. The usual culprit are I think:
>
> * git fetch/clone/pull/.. ;
> * git push ;
> * git repack/gc/... ;
> * git merge (even with the merge.verbosity set to the minimum it's
> still not very readable and confusing).
>
>
> I do believe that the quite verbose output git commands sometimes
> have
> is quite confusing, and let the user think it's messy. I believe that
> porcelains should be more silent, it's OK for the plumbing to spit
> progress messages and so on, because people using the plumbing are
> able
> to understand those, but porcelains should not.
I think that most people just want to know, "Did it work or not?" and
so when the commands chatter too much they go into filter mode, don't
really read the output, let alone try to understand it, and just skim
it. Ideally Git would be much less "chattery" in general when things
work, and only be more verbose when things go wrong; of course,
finding that balance point is where the art lies.
Wincent
^ permalink raw reply
* Re: Obliterating a commit
From: Matthias Kestenholz @ 2007-09-30 12:15 UTC (permalink / raw)
To: Wincent Colaiuta; +Cc: Git Mailing List
In-Reply-To: <D2BD14BD-44F2-4D01-AAEE-6CBC2A2DE85B@wincent.com>
Hello,
2007/9/30, Wincent Colaiuta <win@wincent.com>:
> A couple of days ago I mistakenly checked in a file that had some
> confidential information in it. I immediately realized and amended my
> commit, and this is a local repository whose contents won't be
> visible until I push them out.
>
> So how do I *really* get rid of the that commit before publishing? I
> couldn't find any porcelain or plumbing to do this. Do I have to
> manually destroy it? ie. wind back the HEAD, manually remove the
> commit object, the corresponding tree object, the corresponding file
> blobs, and probably manually remove the entry from the reflog as well?
>
If you use ssh to push your changes (that is, you are not copying
or rsyncing packfiles), only commits, trees and blobs, which are reachable
through the DAG will be published. Commits and Blobs which are only
reachable through your reflog are not published, since the reflog only applies
to your local repository.
The simplest thing you could do is remove the reflog for HEAD and
refs/heads/master respectively your current branch and run 'git prune'
afterwards (if you have not repacked
already, otherwise you'd need to run 'git repack -a -d' or 'git gc' to get
rid of blobs inside your packfile.
> Is there a "shortcut" wherein I can somehow mark this commit and its
> related tree and file blobs as unreachable, and then use git-prune to
> erradicate them?
>
You don't need to mark anything -- it's sufficient that the blob with the
confidential information is only reachable through the reflog (which you
need to remove, obviously, if you want to get rid of the blob locally too)
Cheers,
Matthias
^ 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