From d5b9e6cfa7a20932ca17649c9172619c9d961db4 Mon Sep 17 00:00:00 2001 From: Matthias Lederhofer Date: Fri, 14 Jul 2006 18:37:06 +0200 Subject: argv created by handle_alias should be NULL terminated Signed-off-by: Matthias Lederhofer Signed-off-by: Junio C Hamano --- git.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'git.c') diff --git a/git.c b/git.c index 102735af6c..ee5a0e86a7 100644 --- a/git.c +++ b/git.c @@ -133,13 +133,12 @@ static int handle_alias(int *argcp, const char ***argv) fflush(stderr); } + new_argv = realloc(new_argv, sizeof(char*) * + (count + *argcp + 1)); /* insert after command name */ - if (*argcp > 1) { - new_argv = realloc(new_argv, sizeof(char*) * - (count + *argcp)); - memcpy(new_argv + count, *argv + 1, - sizeof(char*) * *argcp); - } + memcpy(new_argv + count, *argv + 1, + sizeof(char*) * *argcp); + new_argv[count+*argcp] = NULL; *argv = new_argv; *argcp += count - 1; -- cgit v1.3 From 4ab243a944a6013d9e862adadd6fe6152c842401 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 24 Jul 2006 14:10:45 +0200 Subject: Allow an alias to start with "-p" Now, something like [alias] pd = -p diff works as expected. [jc: a follow-up fix from Jeff King folded in.] Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- git.c | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) (limited to 'git.c') diff --git a/git.c b/git.c index ee5a0e86a7..c0bd19d0ef 100644 --- a/git.c +++ b/git.c @@ -35,6 +35,27 @@ static void prepend_to_path(const char *dir, int len) setenv("PATH", path, 1); } +static int handle_options(const char*** argv, int* argc) +{ + int handled = 0; + + while (*argc > 0) { + const char *cmd = (*argv)[0]; + if (cmd[0] != '-') + break; + + if (!strcmp(cmd, "-p") || !strcmp(cmd, "--paginate")) { + setup_pager(); + } else + die ("Unknown option: %s", cmd); + + (*argv)++; + (*argc)--; + handled++; + } + return handled; +} + static const char *alias_command; static char *alias_string = NULL; @@ -106,7 +127,7 @@ static int handle_alias(int *argcp, const char ***argv) subdir = setup_git_directory_gently(&nongit); if (!nongit) { - int count; + int count, option_count; const char** new_argv; alias_command = (*argv)[0]; @@ -114,6 +135,10 @@ static int handle_alias(int *argcp, const char ***argv) if (alias_string) { count = split_cmdline(alias_string, &new_argv); + option_count = handle_options(&new_argv, &count); + memmove(new_argv - option_count, new_argv, + count * sizeof(char *)); + new_argv -= option_count; if (count < 1) die("empty alias for %s", alias_command); @@ -273,13 +298,12 @@ int main(int argc, const char **argv, char **envp) /* Look for flags.. */ while (argc > 1) { - cmd = *++argv; + argv++; argc--; - if (!strcmp(cmd, "-p") || !strcmp(cmd, "--paginate")) { - setup_pager(); - continue; - } + handle_options(&argv, &argc); + + cmd = *argv; if (strncmp(cmd, "--", 2)) break; -- cgit v1.3 From 6acbcb927f8e34857fa8f68fcb4f9076941b24ff Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Tue, 25 Jul 2006 20:24:22 +0200 Subject: git wrapper: add --git-dir= and --bare options With this, you can say git --bare repack -a -d inside a bare repository, and it will actually work. While at it, also move the --version, --help and --exec-path options to the handle_options() function. While at documenting the new options, also document the --paginate option. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- Documentation/git.txt | 12 ++++++- builtin-help.c | 2 +- git.c | 91 ++++++++++++++++++++++++++------------------------- 3 files changed, 58 insertions(+), 47 deletions(-) (limited to 'git.c') diff --git a/Documentation/git.txt b/Documentation/git.txt index ce3058182f..7310a2b8b8 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -8,7 +8,8 @@ git - the stupid content tracker SYNOPSIS -------- -'git' [--version] [--exec-path[=GIT_EXEC_PATH]] [--help] COMMAND [ARGS] +'git' [--version] [--exec-path[=GIT_EXEC_PATH]] [-p|--paginate] + [--bare] [--git-dir=GIT_DIR] [--help] COMMAND [ARGS] DESCRIPTION ----------- @@ -41,6 +42,15 @@ OPTIONS environment variable. If no path is given 'git' will print the current setting and then exit. +-p|--paginate:: + Pipe all output into 'less' (or if set, $PAGER). + +--git-dir=:: + Set the path to the repository. This can also be controlled by + setting the GIT_DIR environment variable. + +--bare:: + Same as --git-dir=`pwd`. FURTHER DOCUMENTATION --------------------- diff --git a/builtin-help.c b/builtin-help.c index 335fe5fedc..bc1b4da3bc 100644 --- a/builtin-help.c +++ b/builtin-help.c @@ -229,7 +229,7 @@ int cmd_version(int argc, const char **argv, char **envp) int cmd_help(int argc, const char **argv, char **envp) { - const char *help_cmd = argv[1]; + const char *help_cmd = argc > 1 ? argv[1] : NULL; if (!help_cmd) cmd_usage(0, git_exec_path(), NULL); else if (!strcmp(help_cmd, "--all") || !strcmp(help_cmd, "-a")) diff --git a/git.c b/git.c index c0bd19d0ef..885e1ce75b 100644 --- a/git.c +++ b/git.c @@ -44,10 +44,42 @@ static int handle_options(const char*** argv, int* argc) if (cmd[0] != '-') break; - if (!strcmp(cmd, "-p") || !strcmp(cmd, "--paginate")) { + /* + * For legacy reasons, the "version" and "help" + * commands can be written with "--" prepended + * to make them look like flags. + */ + if (!strcmp(cmd, "--help") || !strcmp(cmd, "--version")) + break; + + /* + * Check remaining flags. + */ + if (!strncmp(cmd, "--exec-path", 11)) { + cmd += 11; + if (*cmd == '=') + git_set_exec_path(cmd + 1); + else { + puts(git_exec_path()); + exit(0); + } + } else if (!strcmp(cmd, "-p") || !strcmp(cmd, "--paginate")) { setup_pager(); - } else - die ("Unknown option: %s", cmd); + } else if (!strcmp(cmd, "--git-dir")) { + if (*argc < 1) + return -1; + setenv("GIT_DIR", (*argv)[1], 1); + (*argv)++; + (*argc)--; + } else if (!strncmp(cmd, "--git-dir=", 10)) { + setenv("GIT_DIR", cmd + 10, 1); + } else if (!strcmp(cmd, "--bare")) { + static char git_dir[1024]; + setenv("GIT_DIR", getcwd(git_dir, 1024), 1); + } else { + fprintf(stderr, "Unknown option: %s\n", cmd); + cmd_usage(0, NULL, NULL); + } (*argv)++; (*argc)--; @@ -293,50 +325,19 @@ int main(int argc, const char **argv, char **envp) die("cannot handle %s internally", cmd); } - /* Default command: "help" */ - cmd = "help"; - /* Look for flags.. */ - while (argc > 1) { - argv++; - argc--; - - handle_options(&argv, &argc); - - cmd = *argv; - - if (strncmp(cmd, "--", 2)) - break; - - cmd += 2; - - /* - * For legacy reasons, the "version" and "help" - * commands can be written with "--" prepended - * to make them look like flags. - */ - if (!strcmp(cmd, "help")) - break; - if (!strcmp(cmd, "version")) - break; - - /* - * Check remaining flags (which by now must be - * "--exec-path", but maybe we will accept - * other arguments some day) - */ - if (!strncmp(cmd, "exec-path", 9)) { - cmd += 9; - if (*cmd == '=') { - git_set_exec_path(cmd + 1); - continue; - } - puts(git_exec_path()); - exit(0); - } - cmd_usage(0, NULL, NULL); + argv++; + argc--; + handle_options(&argv, &argc); + if (argc > 0) { + if (!strncmp(argv[0], "--", 2)) + argv[0] += 2; + } else { + /* Default command: "help" */ + argv[0] = "help"; + argc = 1; } - argv[0] = cmd; + cmd = argv[0]; /* * We search for git commands in the following order: -- cgit v1.3 From 11be42a47632a6f7219d34f5e312aa20ae076142 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Wed, 26 Jul 2006 03:52:35 +0200 Subject: Make git-mv a builtin This also moves add_file_to_index() to read-cache.c. Oh, and while touching builtin-add.c, it also removes a duplicate git_config() call. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- Makefile | 11 +-- builtin-add.c | 40 ---------- builtin-mv.c | 221 +++++++++++++++++++++++++++++++++++++++++++++++++++ builtin.h | 1 + cache.h | 1 + git-mv.perl | 250 ---------------------------------------------------------- git.c | 1 + read-cache.c | 39 +++++++++ 8 files changed, 269 insertions(+), 295 deletions(-) create mode 100644 builtin-mv.c delete mode 100755 git-mv.perl (limited to 'git.c') diff --git a/Makefile b/Makefile index 49eaa10b3b..73733e9025 100644 --- a/Makefile +++ b/Makefile @@ -151,7 +151,7 @@ SCRIPT_PERL = \ git-archimport.perl git-cvsimport.perl git-relink.perl \ git-shortlog.perl git-rerere.perl \ git-annotate.perl git-cvsserver.perl \ - git-svnimport.perl git-mv.perl git-cvsexportcommit.perl \ + git-svnimport.perl git-cvsexportcommit.perl \ git-send-email.perl git-svn.perl SCRIPT_PYTHON = \ @@ -192,7 +192,7 @@ BUILT_INS = git-log$X git-whatchanged$X git-show$X git-update-ref$X \ git-read-tree$X git-commit-tree$X git-write-tree$X \ git-apply$X git-show-branch$X git-diff-files$X git-update-index$X \ git-diff-index$X git-diff-stages$X git-diff-tree$X git-cat-file$X \ - git-fmt-merge-msg$X git-prune$X + git-fmt-merge-msg$X git-prune$X git-mv$X # what 'all' will build and 'install' will install, in gitexecdir ALL_PROGRAMS = $(PROGRAMS) $(SIMPLE_PROGRAMS) $(SCRIPTS) @@ -221,7 +221,7 @@ LIB_H = \ blob.h cache.h commit.h csum-file.h delta.h \ diff.h object.h pack.h pkt-line.h quote.h refs.h \ run-command.h strbuf.h tag.h tree.h git-compat-util.h revision.h \ - tree-walk.h log-tree.h dir.h + tree-walk.h log-tree.h dir.h path-list.h DIFF_OBJS = \ diff.o diff-lib.o diffcore-break.o diffcore-order.o \ @@ -236,7 +236,7 @@ LIB_OBJS = \ server-info.o setup.o sha1_file.o sha1_name.o strbuf.o \ tag.o tree.o usage.o config.o environment.o ctype.o copy.o \ fetch-clone.o revision.o pager.o tree-walk.o xdiff-interface.o \ - alloc.o merge-file.o $(DIFF_OBJS) + alloc.o merge-file.o path-list.o $(DIFF_OBJS) BUILTIN_OBJS = \ builtin-log.o builtin-help.o builtin-count.o builtin-diff.o builtin-push.o \ @@ -248,7 +248,8 @@ BUILTIN_OBJS = \ builtin-apply.o builtin-show-branch.o builtin-diff-files.o \ builtin-diff-index.o builtin-diff-stages.o builtin-diff-tree.o \ builtin-cat-file.o builtin-mailsplit.o builtin-stripspace.o \ - builtin-update-ref.o builtin-fmt-merge-msg.o builtin-prune.o + builtin-update-ref.o builtin-fmt-merge-msg.o builtin-prune.o \ + builtin-mv.o GITLIBS = $(LIB_FILE) $(XDIFF_LIB) LIBS = $(GITLIBS) -lz diff --git a/builtin-add.c b/builtin-add.c index 3a73a173f7..72d2853176 100644 --- a/builtin-add.c +++ b/builtin-add.c @@ -82,45 +82,6 @@ static void fill_directory(struct dir_struct *dir, const char **pathspec) prune_directory(dir, pathspec, baselen); } -static int add_file_to_index(const char *path, int verbose) -{ - int size, namelen; - struct stat st; - struct cache_entry *ce; - - if (lstat(path, &st)) - die("%s: unable to stat (%s)", path, strerror(errno)); - - if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode)) - die("%s: can only add regular files or symbolic links", path); - - namelen = strlen(path); - size = cache_entry_size(namelen); - ce = xcalloc(1, size); - memcpy(ce->name, path, namelen); - ce->ce_flags = htons(namelen); - fill_stat_cache_info(ce, &st); - - ce->ce_mode = create_ce_mode(st.st_mode); - if (!trust_executable_bit) { - /* If there is an existing entry, pick the mode bits - * from it. - */ - int pos = cache_name_pos(path, namelen); - if (pos >= 0) - ce->ce_mode = active_cache[pos]->ce_mode; - } - - if (index_path(ce->sha1, path, &st, 1)) - die("unable to index file %s", path); - if (add_cache_entry(ce, ADD_CACHE_OK_TO_ADD)) - die("unable to add %s to index",path); - if (verbose) - printf("add '%s'\n", path); - cache_tree_invalidate_path(active_cache_tree, path); - return 0; -} - static struct lock_file lock_file; int cmd_add(int argc, const char **argv, char **envp) @@ -159,7 +120,6 @@ int cmd_add(int argc, const char **argv, char **envp) } die(builtin_add_usage); } - git_config(git_default_config); pathspec = get_pathspec(prefix, argv + i); fill_directory(&dir, pathspec); diff --git a/builtin-mv.c b/builtin-mv.c new file mode 100644 index 0000000000..593ff9e434 --- /dev/null +++ b/builtin-mv.c @@ -0,0 +1,221 @@ +/* + * "git mv" builtin command + * + * Copyright (C) 2006 Johannes Schindelin + */ +#include + +#include "cache.h" +#include "builtin.h" +#include "dir.h" +#include "cache-tree.h" +#include "path-list.h" + +static const char builtin_mv_usage[] = +"git-mv [-n] [-f] ( | [-k] ... )"; + +static const char **copy_pathspec(const char *prefix, const char **pathspec, + int count, int base_name) +{ + const char **result = xmalloc((count + 1) * sizeof(const char *)); + memcpy(result, pathspec, count * sizeof(const char *)); + result[count] = NULL; + if (base_name) { + int i; + for (i = 0; i < count; i++) { + const char *last_slash = strrchr(result[i], '/'); + if (last_slash) + result[i] = last_slash + 1; + } + } + return get_pathspec(prefix, result); +} + +static void show_list(const char *label, struct path_list *list) +{ + if (list->nr > 0) { + int i; + printf("%s", label); + for (i = 0; i < list->nr; i++) + printf("%s%s", i > 0 ? ", " : "", list->items[i].path); + putchar('\n'); + } +} + +static struct lock_file lock_file; + +int cmd_mv(int argc, const char **argv, char **envp) +{ + int i, newfd, count; + int verbose = 0, show_only = 0, force = 0, ignore_errors = 0; + const char *prefix = setup_git_directory(); + const char **source, **destination, **dest_path; + struct stat st; + struct path_list overwritten = {NULL, 0, 0, 0}; + struct path_list src_for_dst = {NULL, 0, 0, 0}; + struct path_list added = {NULL, 0, 0, 0}; + struct path_list deleted = {NULL, 0, 0, 0}; + struct path_list changed = {NULL, 0, 0, 0}; + + git_config(git_default_config); + + newfd = hold_lock_file_for_update(&lock_file, get_index_file()); + if (newfd < 0) + die("unable to create new index file"); + + if (read_cache() < 0) + die("index file corrupt"); + + for (i = 1; i < argc; i++) { + const char *arg = argv[i]; + + if (arg[0] != '-') + break; + if (!strcmp(arg, "--")) { + i++; + break; + } + if (!strcmp(arg, "-n")) { + show_only = 1; + continue; + } + if (!strcmp(arg, "-f")) { + force = 1; + continue; + } + if (!strcmp(arg, "-k")) { + ignore_errors = 1; + continue; + } + die(builtin_mv_usage); + } + count = argc - i - 1; + if (count < 1) + usage(builtin_mv_usage); + + source = copy_pathspec(prefix, argv + i, count, 0); + dest_path = copy_pathspec(prefix, argv + argc - 1, 1, 0); + + if (!lstat(dest_path[0], &st) && S_ISDIR(st.st_mode)) + destination = copy_pathspec(dest_path[0], argv + i, count, 1); + else { + if (count != 1) + usage(builtin_mv_usage); + destination = dest_path; + } + + /* Checking */ + for (i = 0; i < count; i++) { + const char *bad = NULL; + + if (show_only) + printf("Checking rename of '%s' to '%s'\n", + source[i], destination[i]); + + if (lstat(source[i], &st) < 0) + bad = "bad source"; + else if (lstat(destination[i], &st) == 0) { + bad = "destination exists"; + if (force) { + /* + * only files can overwrite each other: + * check both source and destination + */ + if (S_ISREG(st.st_mode)) { + fprintf(stderr, "Warning: %s;" + " will overwrite!\n", + bad); + bad = NULL; + path_list_insert(destination[i], + &overwritten); + } else + bad = "Cannot overwrite"; + } + } + + if (!bad && + !strncmp(destination[i], source[i], strlen(source[i]))) + bad = "can not move directory into itself"; + + if (!bad && cache_name_pos(source[i], strlen(source[i])) < 0) + bad = "not under version control"; + + if (!bad) { + if (path_list_has_path(&src_for_dst, destination[i])) + bad = "multiple sources for the same target"; + else + path_list_insert(destination[i], &src_for_dst); + } + + if (bad) { + if (ignore_errors) { + if (--count > 0) { + memmove(source + i, source + i + 1, + (count - i) * sizeof(char *)); + memmove(destination + i, + destination + i + 1, + (count - i) * sizeof(char *)); + } + } else + die ("Error: %s, source=%s, destination=%s", + bad, source[i], destination[i]); + } + } + + for (i = 0; i < count; i++) { + if (show_only || verbose) + printf("Renaming %s to %s\n", + source[i], destination[i]); + if (!show_only && + rename(source[i], destination[i]) < 0 && + !ignore_errors) + die ("renaming %s failed: %s", + source[i], strerror(errno)); + + if (cache_name_pos(source[i], strlen(source[i])) >= 0) { + path_list_insert(source[i], &deleted); + + /* destination can be a directory with 1 file inside */ + if (path_list_has_path(&overwritten, destination[i])) + path_list_insert(destination[i], &changed); + else + path_list_insert(destination[i], &added); + } else + path_list_insert(destination[i], &added); + } + + if (show_only) { + show_list("Changed : ", &changed); + show_list("Adding : ", &added); + show_list("Deleting : ", &deleted); + } else { + for (i = 0; i < changed.nr; i++) { + const char *path = changed.items[i].path; + int i = cache_name_pos(path, strlen(path)); + struct cache_entry *ce = active_cache[i]; + + if (i < 0) + die ("Huh? Cache entry for %s unknown?", path); + refresh_cache_entry(ce, 0); + } + + for (i = 0; i < added.nr; i++) { + const char *path = added.items[i].path; + add_file_to_index(path, verbose); + } + + for (i = 0; i < deleted.nr; i++) { + const char *path = deleted.items[i].path; + remove_file_from_cache(path); + } + + if (active_cache_changed) { + if (write_cache(newfd, active_cache, active_nr) || + close(newfd) || + commit_lock_file(&lock_file)) + die("Unable to write new index file"); + } + } + + return 0; +} diff --git a/builtin.h b/builtin.h index 5339d8627f..6f3a43957c 100644 --- a/builtin.h +++ b/builtin.h @@ -52,6 +52,7 @@ extern int cmd_rev_parse(int argc, const char **argv, char **envp); extern int cmd_update_index(int argc, const char **argv, char **envp); extern int cmd_update_ref(int argc, const char **argv, char **envp); extern int cmd_fmt_merge_msg(int argc, const char **argv, char **envp); +extern int cmd_mv(int argc, const char **argv, char **envp); extern int cmd_write_tree(int argc, const char **argv, char **envp); extern int write_tree(unsigned char *sha1, int missing_ok, const char *prefix); diff --git a/cache.h b/cache.h index d0b1f2730f..c575b8a996 100644 --- a/cache.h +++ b/cache.h @@ -154,6 +154,7 @@ extern int add_cache_entry(struct cache_entry *ce, int option); extern struct cache_entry *refresh_cache_entry(struct cache_entry *ce, int really); extern int remove_cache_entry_at(int pos); extern int remove_file_from_cache(const char *path); +extern int add_file_to_index(const char *path, int verbose); extern int ce_same_name(struct cache_entry *a, struct cache_entry *b); extern int ce_match_stat(struct cache_entry *ce, struct stat *st, int); extern int ce_modified(struct cache_entry *ce, struct stat *st, int); diff --git a/git-mv.perl b/git-mv.perl deleted file mode 100755 index 75aa8feeb6..0000000000 --- a/git-mv.perl +++ /dev/null @@ -1,250 +0,0 @@ -#!/usr/bin/perl -# -# Copyright 2005, Ryan Anderson -# Josef Weidendorfer -# -# This file is licensed under the GPL v2, or a later version -# at the discretion of Linus Torvalds. - - -use warnings; -use strict; -use Getopt::Std; - -sub usage() { - print < -$0 [-f] [-n] [-k] ... -EOT - exit(1); -} - -our ($opt_n, $opt_f, $opt_h, $opt_k, $opt_v); -getopts("hnfkv") || usage; -usage() if $opt_h; -@ARGV >= 1 or usage; - -my $GIT_DIR = `git rev-parse --git-dir`; -exit 1 if $?; # rev-parse would have given "not a git dir" message. -chomp($GIT_DIR); - -my (@srcArgs, @dstArgs, @srcs, @dsts); -my ($src, $dst, $base, $dstDir); - -# remove any trailing slash in arguments -for (@ARGV) { s/\/*$//; } - -my $argCount = scalar @ARGV; -if (-d $ARGV[$argCount-1]) { - $dstDir = $ARGV[$argCount-1]; - @srcArgs = @ARGV[0..$argCount-2]; - - foreach $src (@srcArgs) { - $base = $src; - $base =~ s/^.*\///; - $dst = "$dstDir/". $base; - push @dstArgs, $dst; - } -} -else { - if ($argCount < 2) { - print "Error: need at least two arguments\n"; - exit(1); - } - if ($argCount > 2) { - print "Error: moving to directory '" - . $ARGV[$argCount-1] - . "' not possible; not existing\n"; - exit(1); - } - @srcArgs = ($ARGV[0]); - @dstArgs = ($ARGV[1]); - $dstDir = ""; -} - -my $subdir_prefix = `git rev-parse --show-prefix`; -chomp($subdir_prefix); - -# run in git base directory, so that git-ls-files lists all revisioned files -chdir "$GIT_DIR/.."; - -# normalize paths, needed to compare against versioned files and update-index -# also, this is nicer to end-users by doing ".//a/./b/.//./c" ==> "a/b/c" -for (@srcArgs, @dstArgs) { - # prepend git prefix as we run from base directory - $_ = $subdir_prefix.$_; - s|^\./||; - s|/\./|/| while (m|/\./|); - s|//+|/|g; - # Also "a/b/../c" ==> "a/c" - 1 while (s,(^|/)[^/]+/\.\./,$1,); -} - -my (@allfiles,@srcfiles,@dstfiles); -my $safesrc; -my (%overwritten, %srcForDst); - -$/ = "\0"; -open(F, 'git-ls-files -z |') - or die "Failed to open pipe from git-ls-files: " . $!; - -@allfiles = map { chomp; $_; } ; -close(F); - - -my ($i, $bad); -while(scalar @srcArgs > 0) { - $src = shift @srcArgs; - $dst = shift @dstArgs; - $bad = ""; - - for ($src, $dst) { - # Be nicer to end-users by doing ".//a/./b/.//./c" ==> "a/b/c" - s|^\./||; - s|/\./|/| while (m|/\./|); - s|//+|/|g; - # Also "a/b/../c" ==> "a/c" - 1 while (s,(^|/)[^/]+/\.\./,$1,); - } - - if ($opt_v) { - print "Checking rename of '$src' to '$dst'\n"; - } - - unless (-f $src || -l $src || -d $src) { - $bad = "bad source '$src'"; - } - - $safesrc = quotemeta($src); - @srcfiles = grep /^$safesrc(\/|$)/, @allfiles; - - $overwritten{$dst} = 0; - if (($bad eq "") && -e $dst) { - $bad = "destination '$dst' already exists"; - if ($opt_f) { - # only files can overwrite each other: check both source and destination - if (-f $dst && (scalar @srcfiles == 1)) { - print "Warning: $bad; will overwrite!\n"; - $bad = ""; - $overwritten{$dst} = 1; - } - else { - $bad = "Can not overwrite '$src' with '$dst'"; - } - } - } - - if (($bad eq "") && ($dst =~ /^$safesrc\//)) { - $bad = "can not move directory '$src' into itself"; - } - - if ($bad eq "") { - if (scalar @srcfiles == 0) { - $bad = "'$src' not under version control"; - } - } - - if ($bad eq "") { - if (defined $srcForDst{$dst}) { - $bad = "can not move '$src' to '$dst'; already target of "; - $bad .= "'".$srcForDst{$dst}."'"; - } - else { - $srcForDst{$dst} = $src; - } - } - - if ($bad ne "") { - if ($opt_k) { - print "Warning: $bad; skipping\n"; - next; - } - print "Error: $bad\n"; - exit(1); - } - push @srcs, $src; - push @dsts, $dst; -} - -# Final pass: rename/move -my (@deletedfiles,@addedfiles,@changedfiles); -$bad = ""; -while(scalar @srcs > 0) { - $src = shift @srcs; - $dst = shift @dsts; - - if ($opt_n || $opt_v) { print "Renaming $src to $dst\n"; } - if (!$opt_n) { - if (!rename($src,$dst)) { - $bad = "renaming '$src' failed: $!"; - if ($opt_k) { - print "Warning: skipped: $bad\n"; - $bad = ""; - next; - } - last; - } - } - - $safesrc = quotemeta($src); - @srcfiles = grep /^$safesrc(\/|$)/, @allfiles; - @dstfiles = @srcfiles; - s/^$safesrc(\/|$)/$dst$1/ for @dstfiles; - - push @deletedfiles, @srcfiles; - if (scalar @srcfiles == 1) { - # $dst can be a directory with 1 file inside - if ($overwritten{$dst} ==1) { - push @changedfiles, $dstfiles[0]; - - } else { - push @addedfiles, $dstfiles[0]; - } - } - else { - push @addedfiles, @dstfiles; - } -} - -if ($opt_n) { - if (@changedfiles) { - print "Changed : ". join(", ", @changedfiles) ."\n"; - } - if (@addedfiles) { - print "Adding : ". join(", ", @addedfiles) ."\n"; - } - if (@deletedfiles) { - print "Deleting : ". join(", ", @deletedfiles) ."\n"; - } -} -else { - if (@changedfiles) { - open(H, "| git-update-index -z --stdin") - or die "git-update-index failed to update changed files with code $!\n"; - foreach my $fileName (@changedfiles) { - print H "$fileName\0"; - } - close(H); - } - if (@addedfiles) { - open(H, "| git-update-index --add -z --stdin") - or die "git-update-index failed to add new names with code $!\n"; - foreach my $fileName (@addedfiles) { - print H "$fileName\0"; - } - close(H); - } - if (@deletedfiles) { - open(H, "| git-update-index --remove -z --stdin") - or die "git-update-index failed to remove old names with code $!\n"; - foreach my $fileName (@deletedfiles) { - print H "$fileName\0"; - } - close(H); - } -} - -if ($bad ne "") { - print "Error: $bad\n"; - exit(1); -} diff --git a/git.c b/git.c index ee5a0e86a7..d47e9d8db9 100644 --- a/git.c +++ b/git.c @@ -202,6 +202,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp) { "update-ref", cmd_update_ref }, { "fmt-merge-msg", cmd_fmt_merge_msg }, { "prune", cmd_prune }, + { "mv", cmd_mv }, }; int i; diff --git a/read-cache.c b/read-cache.c index 4c47a0eb9f..c0b031367b 100644 --- a/read-cache.c +++ b/read-cache.c @@ -319,6 +319,45 @@ int remove_file_from_cache(const char *path) return 0; } +int add_file_to_index(const char *path, int verbose) +{ + int size, namelen; + struct stat st; + struct cache_entry *ce; + + if (lstat(path, &st)) + die("%s: unable to stat (%s)", path, strerror(errno)); + + if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode)) + die("%s: can only add regular files or symbolic links", path); + + namelen = strlen(path); + size = cache_entry_size(namelen); + ce = xcalloc(1, size); + memcpy(ce->name, path, namelen); + ce->ce_flags = htons(namelen); + fill_stat_cache_info(ce, &st); + + ce->ce_mode = create_ce_mode(st.st_mode); + if (!trust_executable_bit) { + /* If there is an existing entry, pick the mode bits + * from it. + */ + int pos = cache_name_pos(path, namelen); + if (pos >= 0) + ce->ce_mode = active_cache[pos]->ce_mode; + } + + if (index_path(ce->sha1, path, &st, 1)) + die("unable to index file %s", path); + if (add_cache_entry(ce, ADD_CACHE_OK_TO_ADD)) + die("unable to add %s to index",path); + if (verbose) + printf("add '%s'\n", path); + cache_tree_invalidate_path(active_cache_tree, path); + return 0; +} + int ce_same_name(struct cache_entry *a, struct cache_entry *b) { int len = ce_namelen(a); -- cgit v1.3 From a633fca0c056aa221d23493c276d3713191621b3 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 28 Jul 2006 22:44:25 -0700 Subject: Call setup_git_directory() much earlier This changes the calling convention of built-in commands and passes the "prefix" (i.e. pathname of $PWD relative to the project root level) down to them. Signed-off-by: Linus Torvalds Signed-off-by: Junio C Hamano --- builtin-add.c | 3 +- builtin-apply.c | 2 +- builtin-cat-file.c | 3 +- builtin-check-ref-format.c | 2 +- builtin-commit-tree.c | 4 +-- builtin-count.c | 2 +- builtin-diff-files.c | 4 +-- builtin-diff-index.c | 4 +-- builtin-diff-stages.c | 3 +- builtin-diff-tree.c | 4 +-- builtin-diff.c | 5 ++- builtin-fmt-merge-msg.c | 3 +- builtin-grep.c | 3 +- builtin-help.c | 4 +-- builtin-init-db.c | 2 +- builtin-log.c | 25 ++++++--------- builtin-ls-files.c | 3 +- builtin-ls-tree.c | 8 ++--- builtin-mailinfo.c | 2 +- builtin-mailsplit.c | 2 +- builtin-prune.c | 4 +-- builtin-push.c | 2 +- builtin-read-tree.c | 3 +- builtin-rev-list.c | 4 +-- builtin-rev-parse.c | 3 +- builtin-rm.c | 3 +- builtin-show-branch.c | 3 +- builtin-stripspace.c | 2 +- builtin-tar-tree.c | 9 +++--- builtin-update-index.c | 3 +- builtin-update-ref.c | 3 +- builtin-upload-tar.c | 2 +- builtin-write-tree.c | 4 +-- builtin.h | 76 +++++++++++++++++++++++----------------------- git.c | 63 +++++++++++++++++++++----------------- 35 files changed, 128 insertions(+), 144 deletions(-) (limited to 'git.c') diff --git a/builtin-add.c b/builtin-add.c index 3a73a173f7..0fa7dc1f11 100644 --- a/builtin-add.c +++ b/builtin-add.c @@ -123,11 +123,10 @@ static int add_file_to_index(const char *path, int verbose) static struct lock_file lock_file; -int cmd_add(int argc, const char **argv, char **envp) +int cmd_add(int argc, const char **argv, const char *prefix) { int i, newfd; int verbose = 0, show_only = 0; - const char *prefix = setup_git_directory(); const char **pathspec; struct dir_struct dir; diff --git a/builtin-apply.c b/builtin-apply.c index d4381d9a8f..f8c6763c74 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -2268,7 +2268,7 @@ static int git_apply_config(const char *var, const char *value) } -int cmd_apply(int argc, const char **argv, char **envp) +int cmd_apply(int argc, const char **argv, const char *prefix) { int i; int read_stdin = 1; diff --git a/builtin-cat-file.c b/builtin-cat-file.c index 4d36817e5f..814fb0743f 100644 --- a/builtin-cat-file.c +++ b/builtin-cat-file.c @@ -94,7 +94,7 @@ static int pprint_tag(const unsigned char *sha1, const char *buf, unsigned long return 0; } -int cmd_cat_file(int argc, const char **argv, char **envp) +int cmd_cat_file(int argc, const char **argv, const char *prefix) { unsigned char sha1[20]; char type[20]; @@ -102,7 +102,6 @@ int cmd_cat_file(int argc, const char **argv, char **envp) unsigned long size; int opt; - setup_git_directory(); git_config(git_default_config); if (argc != 3) usage("git-cat-file [-t|-s|-e|-p|] "); diff --git a/builtin-check-ref-format.c b/builtin-check-ref-format.c index 4a23936aff..701de439ae 100644 --- a/builtin-check-ref-format.c +++ b/builtin-check-ref-format.c @@ -6,7 +6,7 @@ #include "refs.h" #include "builtin.h" -int cmd_check_ref_format(int argc, const char **argv, char **envp) +int cmd_check_ref_format(int argc, const char **argv, const char *prefix) { if (argc != 2) usage("git check-ref-format refname"); diff --git a/builtin-commit-tree.c b/builtin-commit-tree.c index ec082bf754..9c98796671 100644 --- a/builtin-commit-tree.c +++ b/builtin-commit-tree.c @@ -77,7 +77,7 @@ static int new_parent(int idx) return 1; } -int cmd_commit_tree(int argc, const char **argv, char **envp) +int cmd_commit_tree(int argc, const char **argv, const char *prefix) { int i; int parents = 0; @@ -88,8 +88,6 @@ int cmd_commit_tree(int argc, const char **argv, char **envp) unsigned int size; setup_ident(); - setup_git_directory(); - git_config(git_default_config); if (argc < 2) diff --git a/builtin-count.c b/builtin-count.c index 5ee72df247..1d3729aa99 100644 --- a/builtin-count.c +++ b/builtin-count.c @@ -67,7 +67,7 @@ static void count_objects(DIR *d, char *path, int len, int verbose, } } -int cmd_count_objects(int ac, const char **av, char **ep) +int cmd_count_objects(int ac, const char **av, const char *prefix) { int i; int verbose = 0; diff --git a/builtin-diff-files.c b/builtin-diff-files.c index ea2936a5ec..ac13db70ff 100644 --- a/builtin-diff-files.c +++ b/builtin-diff-files.c @@ -13,12 +13,12 @@ static const char diff_files_usage[] = "git-diff-files [-q] [-0/-1/2/3 |-c|--cc] [] [...]" COMMON_DIFF_OPTIONS_HELP; -int cmd_diff_files(int argc, const char **argv, char **envp) +int cmd_diff_files(int argc, const char **argv, const char *prefix) { struct rev_info rev; int silent = 0; - init_revisions(&rev, setup_git_directory()); + init_revisions(&rev, prefix); git_config(git_default_config); /* no "diff" UI options */ rev.abbrev = 0; diff --git a/builtin-diff-index.c b/builtin-diff-index.c index eeeee93fb7..95a3db156b 100644 --- a/builtin-diff-index.c +++ b/builtin-diff-index.c @@ -9,13 +9,13 @@ static const char diff_cache_usage[] = "[] [...]" COMMON_DIFF_OPTIONS_HELP; -int cmd_diff_index(int argc, const char **argv, char **envp) +int cmd_diff_index(int argc, const char **argv, const char *prefix) { struct rev_info rev; int cached = 0; int i; - init_revisions(&rev, setup_git_directory()); + init_revisions(&rev, prefix); git_config(git_default_config); /* no "diff" UI options */ rev.abbrev = 0; diff --git a/builtin-diff-stages.c b/builtin-diff-stages.c index 9c62702941..5960e08997 100644 --- a/builtin-diff-stages.c +++ b/builtin-diff-stages.c @@ -55,10 +55,9 @@ static void diff_stages(int stage1, int stage2, const char **pathspec) } } -int cmd_diff_stages(int ac, const char **av, char **envp) +int cmd_diff_stages(int ac, const char **av, const char *prefix) { int stage1, stage2; - const char *prefix = setup_git_directory(); const char **pathspec = NULL; git_config(git_default_config); /* no "diff" UI options */ diff --git a/builtin-diff-tree.c b/builtin-diff-tree.c index f8215ea707..24cb2d7f84 100644 --- a/builtin-diff-tree.c +++ b/builtin-diff-tree.c @@ -59,7 +59,7 @@ static const char diff_tree_usage[] = " --root include the initial commit as diff against /dev/null\n" COMMON_DIFF_OPTIONS_HELP; -int cmd_diff_tree(int argc, const char **argv, char **envp) +int cmd_diff_tree(int argc, const char **argv, const char *prefix) { int nr_sha1; char line[1000]; @@ -67,7 +67,7 @@ int cmd_diff_tree(int argc, const char **argv, char **envp) static struct rev_info *opt = &log_tree_opt; int read_stdin = 0; - init_revisions(opt, setup_git_directory()); + init_revisions(opt, prefix); git_config(git_default_config); /* no "diff" UI options */ nr_sha1 = 0; opt->abbrev = 0; diff --git a/builtin-diff.c b/builtin-diff.c index 45b27cfca3..48d2fd03b7 100644 --- a/builtin-diff.c +++ b/builtin-diff.c @@ -221,13 +221,13 @@ void add_head(struct rev_info *revs) add_pending_object(revs, obj, "HEAD"); } -int cmd_diff(int argc, const char **argv, char **envp) +int cmd_diff(int argc, const char **argv, const char *prefix) { int i; struct rev_info rev; struct object_array_entry ent[100]; int ents = 0, blobs = 0, paths = 0; - const char *path = NULL, *prefix; + const char *path = NULL; struct blobinfo blob[2]; /* @@ -250,7 +250,6 @@ int cmd_diff(int argc, const char **argv, char **envp) * Other cases are errors. */ - prefix = setup_git_directory(); git_config(git_diff_ui_config); init_revisions(&rev, prefix); diff --git a/builtin-fmt-merge-msg.c b/builtin-fmt-merge-msg.c index 338f2094f3..c84224ee84 100644 --- a/builtin-fmt-merge-msg.c +++ b/builtin-fmt-merge-msg.c @@ -242,7 +242,7 @@ static void shortlog(const char *name, unsigned char *sha1, free_list(&subjects); } -int cmd_fmt_merge_msg(int argc, char **argv, char **envp) +int cmd_fmt_merge_msg(int argc, char **argv, const char *prefix) { int limit = 20, i = 0; char line[1024]; @@ -250,7 +250,6 @@ int cmd_fmt_merge_msg(int argc, char **argv, char **envp) const char *sep = ""; unsigned char head_sha1[20]; const char *head, *current_branch; - const char *prefix = setup_git_directory(); git_config(fmt_merge_msg_config); diff --git a/builtin-grep.c b/builtin-grep.c index a79bac305a..69b7c4862a 100644 --- a/builtin-grep.c +++ b/builtin-grep.c @@ -919,14 +919,13 @@ static const char emsg_missing_context_len[] = static const char emsg_missing_argument[] = "option requires an argument -%s"; -int cmd_grep(int argc, const char **argv, char **envp) +int cmd_grep(int argc, const char **argv, const char *prefix) { int hit = 0; int cached = 0; int seen_dashdash = 0; struct grep_opt opt; struct object_array list = { 0, 0, NULL }; - const char *prefix = setup_git_directory(); const char **paths = NULL; int i; diff --git a/builtin-help.c b/builtin-help.c index bc1b4da3bc..bb0b03f1ae 100644 --- a/builtin-help.c +++ b/builtin-help.c @@ -221,13 +221,13 @@ static void show_man_page(const char *git_cmd) execlp("man", "man", page, NULL); } -int cmd_version(int argc, const char **argv, char **envp) +int cmd_version(int argc, const char **argv, const char *prefix) { printf("git version %s\n", git_version_string); return 0; } -int cmd_help(int argc, const char **argv, char **envp) +int cmd_help(int argc, const char **argv, const char *prefix) { const char *help_cmd = argc > 1 ? argv[1] : NULL; if (!help_cmd) diff --git a/builtin-init-db.c b/builtin-init-db.c index 7fdd2fa9f9..52473edf56 100644 --- a/builtin-init-db.c +++ b/builtin-init-db.c @@ -250,7 +250,7 @@ static const char init_db_usage[] = * On the other hand, it might just make lookup slower and messier. You * be the judge. The default case is to have one DB per managed directory. */ -int cmd_init_db(int argc, const char **argv, char **envp) +int cmd_init_db(int argc, const char **argv, const char *prefix) { const char *git_dir; const char *sha1_dir; diff --git a/builtin-log.c b/builtin-log.c index 52064cd178..82c69d1d05 100644 --- a/builtin-log.c +++ b/builtin-log.c @@ -16,7 +16,7 @@ /* this is in builtin-diff.c */ void add_head(struct rev_info *revs); -static void cmd_log_init(int argc, const char **argv, char **envp, +static void cmd_log_init(int argc, const char **argv, const char *prefix, struct rev_info *rev) { rev->abbrev = DEFAULT_ABBREV; @@ -45,26 +45,24 @@ static int cmd_log_walk(struct rev_info *rev) return 0; } -int cmd_whatchanged(int argc, const char **argv, char **envp) +int cmd_whatchanged(int argc, const char **argv, const char *prefix) { struct rev_info rev; - const char *prefix = setup_git_directory(); git_config(git_diff_ui_config); init_revisions(&rev, prefix); rev.diff = 1; rev.diffopt.recursive = 1; rev.simplify_history = 0; - cmd_log_init(argc, argv, envp, &rev); + cmd_log_init(argc, argv, prefix, &rev); if (!rev.diffopt.output_format) rev.diffopt.output_format = DIFF_FORMAT_RAW; return cmd_log_walk(&rev); } -int cmd_show(int argc, const char **argv, char **envp) +int cmd_show(int argc, const char **argv, const char *prefix) { struct rev_info rev; - const char *prefix = setup_git_directory(); git_config(git_diff_ui_config); init_revisions(&rev, prefix); @@ -75,19 +73,18 @@ int cmd_show(int argc, const char **argv, char **envp) rev.always_show_header = 1; rev.ignore_merges = 0; rev.no_walk = 1; - cmd_log_init(argc, argv, envp, &rev); + cmd_log_init(argc, argv, prefix, &rev); return cmd_log_walk(&rev); } -int cmd_log(int argc, const char **argv, char **envp) +int cmd_log(int argc, const char **argv, const char *prefix) { struct rev_info rev; - const char *prefix = setup_git_directory(); git_config(git_diff_ui_config); init_revisions(&rev, prefix); rev.always_show_header = 1; - cmd_log_init(argc, argv, envp, &rev); + cmd_log_init(argc, argv, prefix, &rev); return cmd_log_walk(&rev); } @@ -181,14 +178,13 @@ static int get_patch_id(struct commit *commit, struct diff_options *options, return diff_flush_patch_id(options, sha1); } -static void get_patch_ids(struct rev_info *rev, struct diff_options *options) +static void get_patch_ids(struct rev_info *rev, struct diff_options *options, const char *prefix) { struct rev_info check_rev; struct commit *commit; struct object *o1, *o2; unsigned flags1, flags2; unsigned char sha1[20]; - const char *prefix = setup_git_directory(); if (rev->pending.nr != 2) die("Need exactly one range."); @@ -244,7 +240,7 @@ static void gen_message_id(char *dest, unsigned int length, char *base) (int)(email_end - email_start - 1), email_start + 1); } -int cmd_format_patch(int argc, const char **argv, char **envp) +int cmd_format_patch(int argc, const char **argv, const char *prefix) { struct commit *commit; struct commit **list = NULL; @@ -261,7 +257,6 @@ int cmd_format_patch(int argc, const char **argv, char **envp) char *add_signoff = NULL; char message_id[1024]; char ref_message_id[1024]; - const char *prefix = setup_git_directory(); git_config(git_format_config); init_revisions(&rev, prefix); @@ -368,7 +363,7 @@ int cmd_format_patch(int argc, const char **argv, char **envp) } if (ignore_if_in_upstream) - get_patch_ids(&rev, &patch_id_opts); + get_patch_ids(&rev, &patch_id_opts, prefix); if (!use_stdout) realstdout = fdopen(dup(1), "w"); diff --git a/builtin-ls-files.c b/builtin-ls-files.c index 8dae9f70e2..79ffe8f423 100644 --- a/builtin-ls-files.c +++ b/builtin-ls-files.c @@ -322,14 +322,13 @@ static const char ls_files_usage[] = "[ --exclude-per-directory= ] [--full-name] [--abbrev] " "[--] []*"; -int cmd_ls_files(int argc, const char **argv, char** envp) +int cmd_ls_files(int argc, const char **argv, const char *prefix) { int i; int exc_given = 0; struct dir_struct dir; memset(&dir, 0, sizeof(dir)); - prefix = setup_git_directory(); if (prefix) prefix_offset = strlen(prefix); git_config(git_default_config); diff --git a/builtin-ls-tree.c b/builtin-ls-tree.c index b8d0d88ba8..261147fdbe 100644 --- a/builtin-ls-tree.c +++ b/builtin-ls-tree.c @@ -18,7 +18,7 @@ static int abbrev = 0; static int ls_options = 0; static const char **pathspec; static int chomp_prefix = 0; -static const char *prefix; +static const char *ls_tree_prefix; static const char ls_tree_usage[] = "git-ls-tree [-d] [-r] [-t] [-z] [--name-only] [--name-status] [--full-name] [--abbrev[=]] [path...]"; @@ -71,7 +71,7 @@ static int show_tree(const unsigned char *sha1, const char *base, int baselen, return 0; if (chomp_prefix && - (baselen < chomp_prefix || memcmp(prefix, base, chomp_prefix))) + (baselen < chomp_prefix || memcmp(ls_tree_prefix, base, chomp_prefix))) return 0; if (!(ls_options & LS_NAME_ONLY)) @@ -85,13 +85,13 @@ static int show_tree(const unsigned char *sha1, const char *base, int baselen, return retval; } -int cmd_ls_tree(int argc, const char **argv, char **envp) +int cmd_ls_tree(int argc, const char **argv, const char *prefix) { unsigned char sha1[20]; struct tree *tree; - prefix = setup_git_directory(); git_config(git_default_config); + ls_tree_prefix = prefix; if (prefix && *prefix) chomp_prefix = strlen(prefix); while (1 < argc && argv[1][0] == '-') { diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c index 05dc1bfe71..24a4fc63b3 100644 --- a/builtin-mailinfo.c +++ b/builtin-mailinfo.c @@ -836,7 +836,7 @@ int mailinfo(FILE *in, FILE *out, int ks, const char *encoding, static const char mailinfo_usage[] = "git-mailinfo [-k] [-u | --encoding=] msg patch info"; -int cmd_mailinfo(int argc, const char **argv, char **envp) +int cmd_mailinfo(int argc, const char **argv, const char *prefix) { /* NEEDSWORK: might want to do the optional .git/ directory * discovery diff --git a/builtin-mailsplit.c b/builtin-mailsplit.c index e2a0058435..91a699d34d 100644 --- a/builtin-mailsplit.c +++ b/builtin-mailsplit.c @@ -138,7 +138,7 @@ out: free(name); return ret; } -int cmd_mailsplit(int argc, const char **argv, char **envp) +int cmd_mailsplit(int argc, const char **argv, const char *prefix) { int nr = 0, nr_prec = 4, ret; int allow_bare = 0; diff --git a/builtin-prune.c b/builtin-prune.c index 4ed1e1b43c..6a86eb52ae 100644 --- a/builtin-prune.c +++ b/builtin-prune.c @@ -217,7 +217,7 @@ static void add_cache_refs(void) add_cache_tree(active_cache_tree); } -int cmd_prune(int argc, const char **argv, char **envp) +int cmd_prune(int argc, const char **argv, const char *prefix) { int i; @@ -234,7 +234,7 @@ int cmd_prune(int argc, const char **argv, char **envp) * Set up revision parsing, and mark us as being interested * in all object types, not just commits. */ - init_revisions(&revs, setup_git_directory()); + init_revisions(&revs, prefix); revs.tag_objects = 1; revs.blob_objects = 1; revs.tree_objects = 1; diff --git a/builtin-push.c b/builtin-push.c index 31cbfd7386..a824171066 100644 --- a/builtin-push.c +++ b/builtin-push.c @@ -270,7 +270,7 @@ static int do_push(const char *repo) return 0; } -int cmd_push(int argc, const char **argv, char **envp) +int cmd_push(int argc, const char **argv, const char *prefix) { int i; const char *repo = "origin"; /* default repository */ diff --git a/builtin-read-tree.c b/builtin-read-tree.c index 122b6f130b..49c10bf221 100644 --- a/builtin-read-tree.c +++ b/builtin-read-tree.c @@ -870,7 +870,7 @@ static const char read_tree_usage[] = "git-read-tree ( | [[-m [--aggressive static struct lock_file lock_file; -int cmd_read_tree(int argc, const char **argv, char **envp) +int cmd_read_tree(int argc, const char **argv, const char *prefix) { int i, newfd, stage = 0; unsigned char sha1[20]; @@ -882,7 +882,6 @@ int cmd_read_tree(int argc, const char **argv, char **envp) state.quiet = 1; state.refresh_cache = 1; - setup_git_directory(); git_config(git_default_config); newfd = hold_lock_file_for_update(&lock_file, get_index_file()); diff --git a/builtin-rev-list.c b/builtin-rev-list.c index 2b6691c8e4..0dee1734a3 100644 --- a/builtin-rev-list.c +++ b/builtin-rev-list.c @@ -306,12 +306,12 @@ static void mark_edges_uninteresting(struct commit_list *list) } } -int cmd_rev_list(int argc, const char **argv, char **envp) +int cmd_rev_list(int argc, const char **argv, const char *prefix) { struct commit_list *list; int i; - init_revisions(&revs, setup_git_directory()); + init_revisions(&revs, prefix); revs.abbrev = 0; revs.commit_format = CMIT_FMT_UNSPECIFIED; argc = setup_revisions(argc, argv, &revs, NULL); diff --git a/builtin-rev-parse.c b/builtin-rev-parse.c index b3e4386c1b..aca4a36032 100644 --- a/builtin-rev-parse.c +++ b/builtin-rev-parse.c @@ -209,11 +209,10 @@ static int try_difference(const char *arg) return 0; } -int cmd_rev_parse(int argc, const char **argv, char **envp) +int cmd_rev_parse(int argc, const char **argv, const char *prefix) { int i, as_is = 0, verify = 0; unsigned char sha1[20]; - const char *prefix = setup_git_directory(); git_config(git_default_config); diff --git a/builtin-rm.c b/builtin-rm.c index bb810ba41a..92d205a715 100644 --- a/builtin-rm.c +++ b/builtin-rm.c @@ -43,11 +43,10 @@ static int remove_file(const char *name) static struct lock_file lock_file; -int cmd_rm(int argc, const char **argv, char **envp) +int cmd_rm(int argc, const char **argv, const char *prefix) { int i, newfd; int verbose = 0, show_only = 0, force = 0; - const char *prefix = setup_git_directory(); const char **pathspec; char *seen; diff --git a/builtin-show-branch.c b/builtin-show-branch.c index 82f75b72de..2a1b848f6c 100644 --- a/builtin-show-branch.c +++ b/builtin-show-branch.c @@ -550,7 +550,7 @@ static int omit_in_dense(struct commit *commit, struct commit **rev, int n) return 0; } -int cmd_show_branch(int ac, const char **av, char **envp) +int cmd_show_branch(int ac, const char **av, const char *prefix) { struct commit *rev[MAX_REVS], *commit; struct commit_list *list = NULL, *seen = NULL; @@ -573,7 +573,6 @@ int cmd_show_branch(int ac, const char **av, char **envp) int topics = 0; int dense = 1; - setup_git_directory(); git_config(git_show_branch_config); /* If nothing is specified, try the default first */ diff --git a/builtin-stripspace.c b/builtin-stripspace.c index 2ce1264f7b..09cc9108cd 100644 --- a/builtin-stripspace.c +++ b/builtin-stripspace.c @@ -54,7 +54,7 @@ void stripspace(FILE *in, FILE *out) fputc('\n', out); } -int cmd_stripspace(int argc, const char **argv, char **envp) +int cmd_stripspace(int argc, const char **argv, const char *prefix) { stripspace(stdin, stdout); return 0; diff --git a/builtin-tar-tree.c b/builtin-tar-tree.c index e5aaded820..7c48db9ec8 100644 --- a/builtin-tar-tree.c +++ b/builtin-tar-tree.c @@ -308,7 +308,7 @@ int git_tar_config(const char *var, const char *value) return git_default_config(var, value); } -static int generate_tar(int argc, const char **argv, char** envp) +static int generate_tar(int argc, const char **argv, const char *prefix) { unsigned char sha1[20], tree_sha1[20]; struct commit *commit; @@ -319,7 +319,6 @@ static int generate_tar(int argc, const char **argv, char** envp) current_path.alloc = PATH_MAX; current_path.len = current_path.eof = 0; - setup_git_directory(); git_config(git_tar_config); switch (argc) { @@ -402,19 +401,19 @@ static int remote_tar(int argc, const char **argv) return !!ret; } -int cmd_tar_tree(int argc, const char **argv, char **envp) +int cmd_tar_tree(int argc, const char **argv, const char *prefix) { if (argc < 2) usage(tar_tree_usage); if (!strncmp("--remote=", argv[1], 9)) return remote_tar(argc, argv); - return generate_tar(argc, argv, envp); + return generate_tar(argc, argv, prefix); } /* ustar header + extended global header content */ #define HEADERSIZE (2 * RECORDSIZE) -int cmd_get_tar_commit_id(int argc, const char **argv, char **envp) +int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix) { char buffer[HEADERSIZE]; struct ustar_header *header = (struct ustar_header *)buffer; diff --git a/builtin-update-index.c b/builtin-update-index.c index 1a4200d151..24dca47d8d 100644 --- a/builtin-update-index.c +++ b/builtin-update-index.c @@ -476,12 +476,11 @@ static int do_reupdate(int ac, const char **av, return 0; } -int cmd_update_index(int argc, const char **argv, char **envp) +int cmd_update_index(int argc, const char **argv, const char *prefix) { int i, newfd, entries, has_errors = 0, line_termination = '\n'; int allow_options = 1; int read_from_stdin = 0; - const char *prefix = setup_git_directory(); int prefix_length = prefix ? strlen(prefix) : 0; char set_executable_bit = 0; unsigned int refresh_flags = 0; diff --git a/builtin-update-ref.c b/builtin-update-ref.c index 83094abe0f..5bd71825fd 100644 --- a/builtin-update-ref.c +++ b/builtin-update-ref.c @@ -5,7 +5,7 @@ static const char git_update_ref_usage[] = "git-update-ref [] [-m ]"; -int cmd_update_ref(int argc, const char **argv, char **envp) +int cmd_update_ref(int argc, const char **argv, const char *prefix) { const char *refname=NULL, *value=NULL, *oldval=NULL, *msg=NULL; struct ref_lock *lock; @@ -13,7 +13,6 @@ int cmd_update_ref(int argc, const char **argv, char **envp) int i; setup_ident(); - setup_git_directory(); git_config(git_default_config); for (i = 1; i < argc; i++) { diff --git a/builtin-upload-tar.c b/builtin-upload-tar.c index d4fa7b56c3..7b401bbb77 100644 --- a/builtin-upload-tar.c +++ b/builtin-upload-tar.c @@ -15,7 +15,7 @@ static int nak(const char *reason) return 1; } -int cmd_upload_tar(int argc, const char **argv, char **envp) +int cmd_upload_tar(int argc, const char **argv, const char *prefix) { int len; const char *dir = argv[1]; diff --git a/builtin-write-tree.c b/builtin-write-tree.c index 449a4d1b57..0289f59936 100644 --- a/builtin-write-tree.c +++ b/builtin-write-tree.c @@ -60,14 +60,12 @@ int write_tree(unsigned char *sha1, int missing_ok, const char *prefix) return 0; } -int cmd_write_tree(int argc, const char **argv, char **envp) +int cmd_write_tree(int argc, const char **argv, const char *unused_prefix) { int missing_ok = 0, ret; const char *prefix = NULL; unsigned char sha1[20]; - setup_git_directory(); - while (1 < argc) { const char *arg = argv[1]; if (!strcmp(arg, "--missing-ok")) diff --git a/builtin.h b/builtin.h index 5339d8627f..de244cdf65 100644 --- a/builtin.h +++ b/builtin.h @@ -15,53 +15,53 @@ void cmd_usage(int show_all, const char *exec_path, const char *fmt, ...) #endif ; -extern int cmd_help(int argc, const char **argv, char **envp); -extern int cmd_version(int argc, const char **argv, char **envp); +extern int cmd_help(int argc, const char **argv, const char *prefix); +extern int cmd_version(int argc, const char **argv, const char *prefix); -extern int cmd_whatchanged(int argc, const char **argv, char **envp); -extern int cmd_show(int argc, const char **argv, char **envp); -extern int cmd_log(int argc, const char **argv, char **envp); -extern int cmd_diff(int argc, const char **argv, char **envp); -extern int cmd_format_patch(int argc, const char **argv, char **envp); -extern int cmd_count_objects(int argc, const char **argv, char **envp); +extern int cmd_whatchanged(int argc, const char **argv, const char *prefix); +extern int cmd_show(int argc, const char **argv, const char *prefix); +extern int cmd_log(int argc, const char **argv, const char *prefix); +extern int cmd_diff(int argc, const char **argv, const char *prefix); +extern int cmd_format_patch(int argc, const char **argv, const char *prefix); +extern int cmd_count_objects(int argc, const char **argv, const char *prefix); -extern int cmd_prune(int argc, const char **argv, char **envp); +extern int cmd_prune(int argc, const char **argv, const char *prefix); -extern int cmd_push(int argc, const char **argv, char **envp); -extern int cmd_grep(int argc, const char **argv, char **envp); -extern int cmd_rm(int argc, const char **argv, char **envp); -extern int cmd_add(int argc, const char **argv, char **envp); -extern int cmd_rev_list(int argc, const char **argv, char **envp); -extern int cmd_check_ref_format(int argc, const char **argv, char **envp); -extern int cmd_init_db(int argc, const char **argv, char **envp); -extern int cmd_tar_tree(int argc, const char **argv, char **envp); -extern int cmd_upload_tar(int argc, const char **argv, char **envp); -extern int cmd_get_tar_commit_id(int argc, const char **argv, char **envp); -extern int cmd_ls_files(int argc, const char **argv, char **envp); -extern int cmd_ls_tree(int argc, const char **argv, char **envp); -extern int cmd_read_tree(int argc, const char **argv, char **envp); -extern int cmd_commit_tree(int argc, const char **argv, char **envp); -extern int cmd_apply(int argc, const char **argv, char **envp); -extern int cmd_show_branch(int argc, const char **argv, char **envp); -extern int cmd_diff_files(int argc, const char **argv, char **envp); -extern int cmd_diff_index(int argc, const char **argv, char **envp); -extern int cmd_diff_stages(int argc, const char **argv, char **envp); -extern int cmd_diff_tree(int argc, const char **argv, char **envp); -extern int cmd_cat_file(int argc, const char **argv, char **envp); -extern int cmd_rev_parse(int argc, const char **argv, char **envp); -extern int cmd_update_index(int argc, const char **argv, char **envp); -extern int cmd_update_ref(int argc, const char **argv, char **envp); -extern int cmd_fmt_merge_msg(int argc, const char **argv, char **envp); +extern int cmd_push(int argc, const char **argv, const char *prefix); +extern int cmd_grep(int argc, const char **argv, const char *prefix); +extern int cmd_rm(int argc, const char **argv, const char *prefix); +extern int cmd_add(int argc, const char **argv, const char *prefix); +extern int cmd_rev_list(int argc, const char **argv, const char *prefix); +extern int cmd_check_ref_format(int argc, const char **argv, const char *prefix); +extern int cmd_init_db(int argc, const char **argv, const char *prefix); +extern int cmd_tar_tree(int argc, const char **argv, const char *prefix); +extern int cmd_upload_tar(int argc, const char **argv, const char *prefix); +extern int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix); +extern int cmd_ls_files(int argc, const char **argv, const char *prefix); +extern int cmd_ls_tree(int argc, const char **argv, const char *prefix); +extern int cmd_read_tree(int argc, const char **argv, const char *prefix); +extern int cmd_commit_tree(int argc, const char **argv, const char *prefix); +extern int cmd_apply(int argc, const char **argv, const char *prefix); +extern int cmd_show_branch(int argc, const char **argv, const char *prefix); +extern int cmd_diff_files(int argc, const char **argv, const char *prefix); +extern int cmd_diff_index(int argc, const char **argv, const char *prefix); +extern int cmd_diff_stages(int argc, const char **argv, const char *prefix); +extern int cmd_diff_tree(int argc, const char **argv, const char *prefix); +extern int cmd_cat_file(int argc, const char **argv, const char *prefix); +extern int cmd_rev_parse(int argc, const char **argv, const char *prefix); +extern int cmd_update_index(int argc, const char **argv, const char *prefix); +extern int cmd_update_ref(int argc, const char **argv, const char *prefix); +extern int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix); -extern int cmd_write_tree(int argc, const char **argv, char **envp); +extern int cmd_write_tree(int argc, const char **argv, const char *prefix); extern int write_tree(unsigned char *sha1, int missing_ok, const char *prefix); -extern int cmd_mailsplit(int argc, const char **argv, char **envp); +extern int cmd_mailsplit(int argc, const char **argv, const char *prefix); extern int split_mbox(const char **mbox, const char *dir, int allow_bare, int nr_prec, int skip); -extern int cmd_mailinfo(int argc, const char **argv, char **envp); +extern int cmd_mailinfo(int argc, const char **argv, const char *prefix); extern int mailinfo(FILE *in, FILE *out, int ks, const char *encoding, const char *msg, const char *patch); -extern int cmd_stripspace(int argc, const char **argv, char **envp); +extern int cmd_stripspace(int argc, const char **argv, const char *prefix); extern void stripspace(FILE *in, FILE *out); #endif diff --git a/git.c b/git.c index 885e1ce75b..79db43e143 100644 --- a/git.c +++ b/git.c @@ -214,51 +214,54 @@ static int handle_alias(int *argcp, const char ***argv) const char git_version_string[] = GIT_VERSION; +#define NEEDS_PREFIX 1 + static void handle_internal_command(int argc, const char **argv, char **envp) { const char *cmd = argv[0]; static struct cmd_struct { const char *cmd; - int (*fn)(int, const char **, char **); + int (*fn)(int, const char **, const char *); + int prefix; } commands[] = { { "version", cmd_version }, { "help", cmd_help }, - { "log", cmd_log }, - { "whatchanged", cmd_whatchanged }, - { "show", cmd_show }, + { "log", cmd_log, NEEDS_PREFIX }, + { "whatchanged", cmd_whatchanged, NEEDS_PREFIX }, + { "show", cmd_show, NEEDS_PREFIX }, { "push", cmd_push }, - { "format-patch", cmd_format_patch }, + { "format-patch", cmd_format_patch, NEEDS_PREFIX }, { "count-objects", cmd_count_objects }, - { "diff", cmd_diff }, - { "grep", cmd_grep }, - { "rm", cmd_rm }, - { "add", cmd_add }, - { "rev-list", cmd_rev_list }, + { "diff", cmd_diff, NEEDS_PREFIX }, + { "grep", cmd_grep, NEEDS_PREFIX }, + { "rm", cmd_rm, NEEDS_PREFIX }, + { "add", cmd_add, NEEDS_PREFIX }, + { "rev-list", cmd_rev_list, NEEDS_PREFIX }, { "init-db", cmd_init_db }, { "get-tar-commit-id", cmd_get_tar_commit_id }, { "upload-tar", cmd_upload_tar }, { "check-ref-format", cmd_check_ref_format }, - { "ls-files", cmd_ls_files }, - { "ls-tree", cmd_ls_tree }, - { "tar-tree", cmd_tar_tree }, - { "read-tree", cmd_read_tree }, - { "commit-tree", cmd_commit_tree }, + { "ls-files", cmd_ls_files, NEEDS_PREFIX }, + { "ls-tree", cmd_ls_tree, NEEDS_PREFIX }, + { "tar-tree", cmd_tar_tree, NEEDS_PREFIX }, + { "read-tree", cmd_read_tree, NEEDS_PREFIX }, + { "commit-tree", cmd_commit_tree, NEEDS_PREFIX }, { "apply", cmd_apply }, - { "show-branch", cmd_show_branch }, - { "diff-files", cmd_diff_files }, - { "diff-index", cmd_diff_index }, - { "diff-stages", cmd_diff_stages }, - { "diff-tree", cmd_diff_tree }, - { "cat-file", cmd_cat_file }, - { "rev-parse", cmd_rev_parse }, - { "write-tree", cmd_write_tree }, + { "show-branch", cmd_show_branch, NEEDS_PREFIX }, + { "diff-files", cmd_diff_files, NEEDS_PREFIX }, + { "diff-index", cmd_diff_index, NEEDS_PREFIX }, + { "diff-stages", cmd_diff_stages, NEEDS_PREFIX }, + { "diff-tree", cmd_diff_tree, NEEDS_PREFIX }, + { "cat-file", cmd_cat_file, NEEDS_PREFIX }, + { "rev-parse", cmd_rev_parse, NEEDS_PREFIX }, + { "write-tree", cmd_write_tree, NEEDS_PREFIX }, { "mailsplit", cmd_mailsplit }, { "mailinfo", cmd_mailinfo }, { "stripspace", cmd_stripspace }, - { "update-index", cmd_update_index }, - { "update-ref", cmd_update_ref }, - { "fmt-merge-msg", cmd_fmt_merge_msg }, - { "prune", cmd_prune }, + { "update-index", cmd_update_index, NEEDS_PREFIX }, + { "update-ref", cmd_update_ref, NEEDS_PREFIX }, + { "fmt-merge-msg", cmd_fmt_merge_msg, NEEDS_PREFIX }, + { "prune", cmd_prune, NEEDS_PREFIX }, }; int i; @@ -270,9 +273,13 @@ static void handle_internal_command(int argc, const char **argv, char **envp) for (i = 0; i < ARRAY_SIZE(commands); i++) { struct cmd_struct *p = commands+i; + const char *prefix; if (strcmp(p->cmd, cmd)) continue; + prefix = NULL; + if (p->prefix) + prefix = setup_git_directory(); if (getenv("GIT_TRACE")) { int i; fprintf(stderr, "trace: built-in: git"); @@ -284,7 +291,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp) fflush(stderr); } - exit(p->fn(argc, argv, envp)); + exit(p->fn(argc, argv, prefix)); } } -- cgit v1.3 From 0347a8c7648ea9504badce7bb4ed4c4f3dbacf16 Mon Sep 17 00:00:00 2001 From: Matthias Lederhofer Date: Sun, 30 Jul 2006 03:30:29 +0200 Subject: git.c: allow alias expansion without a git directory With this, the configuration mechanism can be used to say: [alias] init = init-db --template=/path/to/template Signed-off-by: Matthias Lederhofer Signed-off-by: Junio C Hamano --- git.c | 76 ++++++++++++++++++++++++++++++++----------------------------------- 1 file changed, 36 insertions(+), 40 deletions(-) (limited to 'git.c') diff --git a/git.c b/git.c index 452180e23a..7321d6c3f6 100644 --- a/git.c +++ b/git.c @@ -156,52 +156,48 @@ static int handle_alias(int *argcp, const char ***argv) { int nongit = 0, ret = 0, saved_errno = errno; const char *subdir; + int count, option_count; + const char** new_argv; subdir = setup_git_directory_gently(&nongit); - if (!nongit) { - int count, option_count; - const char** new_argv; - - alias_command = (*argv)[0]; - git_config(git_alias_config); - if (alias_string) { - - count = split_cmdline(alias_string, &new_argv); - option_count = handle_options(&new_argv, &count); - memmove(new_argv - option_count, new_argv, - count * sizeof(char *)); - new_argv -= option_count; - - if (count < 1) - die("empty alias for %s", alias_command); - - if (!strcmp(alias_command, new_argv[0])) - die("recursive alias: %s", alias_command); - - if (getenv("GIT_TRACE")) { - int i; - fprintf(stderr, "trace: alias expansion: %s =>", - alias_command); - for (i = 0; i < count; ++i) { - fputc(' ', stderr); - sq_quote_print(stderr, new_argv[i]); - } - fputc('\n', stderr); - fflush(stderr); - } - new_argv = realloc(new_argv, sizeof(char*) * - (count + *argcp + 1)); - /* insert after command name */ - memcpy(new_argv + count, *argv + 1, - sizeof(char*) * *argcp); - new_argv[count+*argcp] = NULL; + alias_command = (*argv)[0]; + git_config(git_alias_config); + if (alias_string) { + count = split_cmdline(alias_string, &new_argv); + option_count = handle_options(&new_argv, &count); + memmove(new_argv - option_count, new_argv, + count * sizeof(char *)); + new_argv -= option_count; + + if (count < 1) + die("empty alias for %s", alias_command); - *argv = new_argv; - *argcp += count - 1; + if (!strcmp(alias_command, new_argv[0])) + die("recursive alias: %s", alias_command); - ret = 1; + if (getenv("GIT_TRACE")) { + int i; + fprintf(stderr, "trace: alias expansion: %s =>", + alias_command); + for (i = 0; i < count; ++i) { + fputc(' ', stderr); + sq_quote_print(stderr, new_argv[i]); + } + fputc('\n', stderr); + fflush(stderr); } + + new_argv = realloc(new_argv, sizeof(char*) * + (count + *argcp + 1)); + /* insert after command name */ + memcpy(new_argv + count, *argv + 1, sizeof(char*) * *argcp); + new_argv[count+*argcp] = NULL; + + *argv = new_argv; + *argcp += count - 1; + + ret = 1; } if (subdir) -- cgit v1.3