diff options
-rw-r--r-- | Documentation/config.txt | 181 | ||||
-rw-r--r-- | Documentation/git-repo-config.txt | 29 | ||||
-rw-r--r-- | Documentation/git-var.txt | 5 | ||||
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | config.c | 2 | ||||
-rw-r--r-- | contrib/colordiff/README | 2 | ||||
-rwxr-xr-x | contrib/colordiff/colordiff.perl | 196 | ||||
-rw-r--r-- | daemon.c | 2 | ||||
-rwxr-xr-x | gitk | 20 | ||||
-rw-r--r-- | rev-parse.c | 12 | ||||
-rw-r--r-- | revision.c | 3 | ||||
-rw-r--r-- | update-index.c | 150 |
12 files changed, 559 insertions, 45 deletions
diff --git a/Documentation/config.txt b/Documentation/config.txt new file mode 100644 index 0000000000..b27b0d5c06 --- /dev/null +++ b/Documentation/config.txt @@ -0,0 +1,181 @@ +CONFIGURATION FILE +------------------ + +The git configuration file contains a number of variables that affect +the git commands behaviour. They can be used by both the git plumbing +and the porcelains. The variables are divided to sections, where +in the fully qualified variable name the variable itself is the last +dot-separated segment and the section name is everything before the last +dot. The variable names are case-insensitive and only alphanumeric +characters are allowed. Some variables may appear multiple times. + +The syntax is fairly flexible and permissive; whitespaces are mostly +ignored. The '#' and ';' characters begin commends to the end of line, +blank lines are ignored, lines containing strings enclosed in square +brackets start sections and all the other lines are recognized +as setting variables, in the form 'name = value'. If there is no equal +sign on the line, the entire line is taken as 'name' and the variable +is recognized as boolean "true". String values may be entirely or partially +enclosed in double quotes; some variables may require special value format. + +Example +~~~~~~~ + + # Core variables + [core] + ; Don't trust file modes + filemode = false + + # Our diff algorithm + [diff] + external = "/usr/local/bin/gnu-diff -u" + renames = true + +Variables +~~~~~~~~~ + +Note that this list is non-comprehensive and not necessarily complete. +For command-specific variables, you will find more detailed description +in the appropriate manual page. You will find description of non-core +porcelain configuration variables in the respective porcelain documentation. + +core.fileMode:: + If false, the executable bit differences between the index and + the working copy are ignored; useful on broken filesystems like FAT. + See gitlink:git-update-index[1]. True by default. + +core.gitProxy:: + A "proxy command" to execute (as 'command host port') instead + of establishing direct connection to the remote server when + using the git protocol for fetching. If the variable value is + in the "COMMAND for DOMAIN" format, the command is applied only + on hostnames ending with the specified domain string. This variable + may be set multiple times and is matched in the given order; + the first match wins. + + Can be overriden by the 'GIT_PROXY_COMMAND' environment variable + (which always applies universally, without the special "for" + handling). + +core.ignoreStat:: + The working copy files are assumed to stay unchanged until you + mark them otherwise manually - Git will not detect the file changes + by lstat() calls. This is useful on systems where those are very + slow, such as Microsoft Windows. See gitlink:git-update-index[1]. + False by default. + +core.onlyUseSymrefs:: + Always use the "symref" format instead of symbolic links for HEAD + and other symbolic reference files. True by default. + +core.repositoryFormatVersion:: + Internal variable identifying the repository format and layout + version. + +core.sharedRepository:: + If true, the repository is made shareable between several users + in a group (making sure all the files and objects are group-writable). + See gitlink:git-init-db[1]. False by default. + +core.warnAmbiguousRefs:: + If true, git will warn you if the ref name you passed it is ambiguous + and might match multiple refs in the .git/refs/ tree. True by default. + +apply.whitespace:: + Tells `git-apply` how to handle whitespaces, in the same way + as the '--whitespace' option. See gitlink:git-apply[1]. + +diff.renameLimit:: + The number of files to consider when performing the copy/rename + detection; equivalent to the git diff option '-l'. + +format.headers:: + Additional email headers to include in a patch to be submitted + by mail. See gitlink:git-format-patch[1]. + +gitcvs.enabled:: + Whether the cvs pserver interface is enabled for this repository. + See gitlink:git-cvsserver[1]. + +gitcvs.logfile:: + Path to a log file where the cvs pserver interface well... logs + various stuff. See gitlink:git-cvsserver[1]. + +http.sslVerify:: + Whether to verify the SSL certificate when fetching or pushing + over HTTPS. Can be overriden by the 'GIT_SSL_NO_VERIFY' environment + variable. + +http.sslCert:: + File containing the SSL certificate when fetching or pushing + over HTTPS. Can be overriden by the 'GIT_SSL_CERT' environment + variable. + +http.sslKey:: + File containing the SSL private key when fetching or pushing + over HTTPS. Can be overriden by the 'GIT_SSL_KEY' environment + variable. + +http.sslCAInfo:: + File containing the certificates to verify the peer with when + fetching or pushing over HTTPS. Can be overriden by the + 'GIT_SSL_CAINFO' environment variable. + +http.sslCAPath:: + Path containing files with the CA certificates to verify the peer + with when fetching or pushing over HTTPS. Can be overriden + by the 'GIT_SSL_CAPATH' environment variable. + +http.maxRequests:: + How many HTTP requests to launch in parallel. Can be overriden + by the 'GIT_HTTP_MAX_REQUESTS' environment variable. Default is 5. + +http.lowSpeedLimit, http.lowSpeedTime:: + If the HTTP transfer speed is less than 'http.lowSpeedLimit' + for longer than 'http.lowSpeedTime' seconds, the transfer is aborted. + Can be overriden by the 'GIT_HTTP_LOW_SPEED_LIMIT' and + 'GIT_HTTP_LOW_SPEED_TIME' environment variables. + +i18n.commitEncoding:: + Character encoding the commit messages are stored in; git itself + does not care per se, but this information is necessary e.g. when + importing commits from emails or in the gitk graphical history + browser (and possibly at other places in the future or in other + porcelains). See e.g. gitlink:git-mailinfo[1]. Defaults to 'utf-8'. + +merge.summary:: + Whether to include summaries of merged commits in newly created + merge commit messages. False by default. + +pull.octopus:: + The default merge strategy to use when pulling multiple branches + at once. + +pull.twohead:: + The default merge strategy to use when pulling a single branch. + +show.difftree:: + The default gitlink:git-diff-tree[1] arguments to be used + for gitlink:git-show[1]. + +showbranch.default:: + The default set of branches for gitlink:git-show-branch[1]. + See gitlink:git-show-branch[1]. + +user.email:: + Your email address to be recorded in any newly created commits. + Can be overriden by the 'GIT_AUTHOR_EMAIL' and 'GIT_COMMITTER_EMAIL' + environment variables. See gitlink:git-commit-tree[1]. + +user.name:: + Your full name to be recorded in any newly created commits. + Can be overriden by the 'GIT_AUTHOR_NAME' and 'GIT_COMMITTER_NAME' + environment variables. See gitlink:git-commit-tree[1]. + +whatchanged.difftree:: + The default gitlink:git-diff-tree[1] arguments to be used + for gitlink:git-whatchanged[1]. + +imap:: + The configuration variables in the 'imap' section are described + in gitlink:git-imap-send[1]. diff --git a/Documentation/git-repo-config.txt b/Documentation/git-repo-config.txt index 26759a8071..71f96bdd10 100644 --- a/Documentation/git-repo-config.txt +++ b/Documentation/git-repo-config.txt @@ -87,11 +87,11 @@ Given a .git/config like this: renames = true ; Proxy settings - [proxy] - command="ssh" for "ssh://kernel.org/" - command="proxy-command" for kernel.org - command="myprotocol-command" for "my://" - command=default-proxy ; for all the rest + [core] + gitproxy="ssh" for "ssh://kernel.org/" + gitproxy="proxy-command" for kernel.org + gitproxy="myprotocol-command" for "my://" + gitproxy=default-proxy ; for all the rest you can set the filemode to true with @@ -104,7 +104,7 @@ to what URL they apply. Here is how to change the entry for kernel.org to "ssh". ------------ -% git repo-config proxy.command '"ssh" for kernel.org' 'for kernel.org$' +% git repo-config core.gitproxy '"ssh" for kernel.org' 'for kernel.org$' ------------ This makes sure that only the key/value pair for kernel.org is replaced. @@ -115,7 +115,7 @@ To delete the entry for renames, do % git repo-config --unset diff.renames ------------ -If you want to delete an entry for a multivar (like proxy.command above), +If you want to delete an entry for a multivar (like core.gitproxy above), you have to provide a regex matching the value of exactly one line. To query the value for a given key, do @@ -133,27 +133,27 @@ or or, to query a multivar: ------------ -% git repo-config --get proxy.command "for kernel.org$" +% git repo-config --get core.gitproxy "for kernel.org$" ------------ If you want to know all the values for a multivar, do: ------------ -% git repo-config --get-all proxy.command +% git repo-config --get-all core.gitproxy ------------ -If you like to live dangerous, you can replace *all* proxy.commands by a +If you like to live dangerous, you can replace *all* core.gitproxy by a new one with ------------ -% git repo-config --replace-all proxy.command ssh +% git repo-config --replace-all core.gitproxy ssh ------------ However, if you really only want to replace the line for the default proxy, i.e. the one without a "for ..." postfix, do something like this: ------------ -% git repo-config proxy.command ssh '! for ' +% git repo-config core.gitproxy ssh '! for ' ------------ To actually match only values with an exclamation mark, you have to @@ -163,13 +163,16 @@ To actually match only values with an exclamation mark, you have to ------------ +include::config.txt[] + + Author ------ Written by Johannes Schindelin <Johannes.Schindelin@gmx.de> Documentation -------------- -Documentation by Johannes Schindelin. +Documentation by Johannes Schindelin, Petr Baudis and the git-list <git@vger.kernel.org>. GIT --- diff --git a/Documentation/git-var.txt b/Documentation/git-var.txt index 90cb157be5..379571eef0 100644 --- a/Documentation/git-var.txt +++ b/Documentation/git-var.txt @@ -17,7 +17,9 @@ Prints a git logical variable. OPTIONS ------- -l:: - Cause the logical variables to be listed. + Cause the logical variables to be listed. In addition, all the + variables of the git configuration file .git/config are listed + as well. EXAMPLE -------- @@ -46,6 +48,7 @@ See Also -------- gitlink:git-commit-tree[1] gitlink:git-tag[1] +gitlink:git-repo-config[1] Author ------ @@ -575,7 +575,7 @@ $(patsubst git-%$X,%.o,$(PROGRAMS)): $(GITLIBS) $(DIFF_OBJS): diffcore.h $(LIB_FILE): $(LIB_OBJS) - $(AR) rcs $@ $(LIB_OBJS) + rm -f $@ && $(AR) rcs $@ $(LIB_OBJS) XDIFF_OBJS=xdiff/xdiffi.o xdiff/xprepare.o xdiff/xutils.o xdiff/xemit.o @@ -252,7 +252,7 @@ int git_default_config(const char *var, const char *value) return 0; } - /* Add other config variables here.. */ + /* Add other config variables here and to Documentation/config.txt. */ return 0; } diff --git a/contrib/colordiff/README b/contrib/colordiff/README new file mode 100644 index 0000000000..2678fdf9c2 --- /dev/null +++ b/contrib/colordiff/README @@ -0,0 +1,2 @@ +This is "colordiff" (http://colordiff.sourceforge.net/) by Dave +Ewart <davee@sungate.co.uk>, modified specifically for git. diff --git a/contrib/colordiff/colordiff.perl b/contrib/colordiff/colordiff.perl new file mode 100755 index 0000000000..5789cfb265 --- /dev/null +++ b/contrib/colordiff/colordiff.perl @@ -0,0 +1,196 @@ +#!/usr/bin/perl -w +# +# $Id: colordiff.pl,v 1.4.2.10 2004/01/04 15:02:59 daveewart Exp $ + +######################################################################## +# # +# ColorDiff - a wrapper/replacment for 'diff' producing # +# colourful output # +# # +# Copyright (C)2002-2004 Dave Ewart (davee@sungate.co.uk) # +# # +######################################################################## +# # +# This program is free software; you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation; either version 2 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program; if not, write to the Free Software # +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # +# # +######################################################################## + +use strict; +use Getopt::Long qw(:config pass_through); +use IPC::Open2; + +my $app_name = 'colordiff'; +my $version = '1.0.4'; +my $author = 'Dave Ewart'; +my $author_email = 'davee@sungate.co.uk'; +my $app_www = 'http://colordiff.sourceforge.net/'; +my $copyright = '(C)2002-2004'; +my $show_banner = 1; + +# ANSI sequences for colours +my %colour; +$colour{white} = "\033[1;37m"; +$colour{yellow} = "\033[1;33m"; +$colour{green} = "\033[1;32m"; +$colour{blue} = "\033[1;34m"; +$colour{cyan} = "\033[1;36m"; +$colour{red} = "\033[1;31m"; +$colour{magenta} = "\033[1;35m"; +$colour{black} = "\033[1;30m"; +$colour{darkwhite} = "\033[0;37m"; +$colour{darkyellow} = "\033[0;33m"; +$colour{darkgreen} = "\033[0;32m"; +$colour{darkblue} = "\033[0;34m"; +$colour{darkcyan} = "\033[0;36m"; +$colour{darkred} = "\033[0;31m"; +$colour{darkmagenta} = "\033[0;35m"; +$colour{darkblack} = "\033[0;30m"; +$colour{OFF} = "\033[0;0m"; + +# Default colours if /etc/colordiffrc or ~/.colordiffrc do not exist +my $plain_text = $colour{OFF}; +my $file_old = $colour{red}; +my $file_new = $colour{blue}; +my $diff_stuff = $colour{magenta}; + +# Locations for personal and system-wide colour configurations +my $HOME = $ENV{HOME}; +my $etcdir = '/etc'; + +my ($setting, $value); +my @config_files = ("$etcdir/colordiffrc", "$HOME/.colordiffrc"); +my $config_file; + +foreach $config_file (@config_files) { + if (open(COLORDIFFRC, "<$config_file")) { + while (<COLORDIFFRC>) { + chop; + next if (/^#/ || /^$/); + s/\s+//g; + ($setting, $value) = split ('='); + if ($setting eq 'banner') { + if ($value eq 'no') { + $show_banner = 0; + } + next; + } + if (!defined $colour{$value}) { + print "Invalid colour specification ($value) in $config_file\n"; + next; + } + if ($setting eq 'plain') { + $plain_text = $colour{$value}; + } + elsif ($setting eq 'oldtext') { + $file_old = $colour{$value}; + } + elsif ($setting eq 'newtext') { + $file_new = $colour{$value}; + } + elsif ($setting eq 'diffstuff') { + $diff_stuff = $colour{$value}; + } + else { + print "Unknown option in $etcdir/colordiffrc: $setting\n"; + } + } + close COLORDIFFRC; + } +} + +# colordiff specfic options here. Need to pre-declare if using variables +GetOptions( + "no-banner" => sub { $show_banner = 0 }, + "plain-text=s" => \&set_color, + "file-old=s" => \&set_color, + "file-new=s" => \&set_color, + "diff-stuff=s" => \&set_color +); + +if ($show_banner == 1) { + print STDERR "$app_name $version ($app_www)\n"; + print STDERR "$copyright $author, $author_email\n\n"; +} + +if (defined $ARGV[0]) { + # More reliable way of pulling in arguments + open2(\*INPUTSTREAM, undef, "git", "diff", @ARGV); +} +else { + *INPUTSTREAM = \*STDIN; +} + +my $record; +my $nrecs = 0; +my $inside_file_old = 1; +my $nparents = undef; + +while (<INPUTSTREAM>) { + $nrecs++; + if (/^(\@\@+) -[-+0-9, ]+ \1/) { + print "$diff_stuff"; + $nparents = length($1) - 1; + } + elsif (/^diff -/ || /^index / || + /^old mode / || /^new mode / || + /^deleted file mode / || /^new file mode / || + /^similarity index / || /^dissimilarity index / || + /^copy from / || /^copy to / || + /^rename from / || /^rename to /) { + $nparents = undef; + print "$diff_stuff"; + } + elsif (defined $nparents) { + if ($nparents == 1) { + if (/^\+/) { + print $file_new; + } + elsif (/^-/) { + print $file_old; + } + else { + print $plain_text; + } + } + elsif (/^ {$nparents}/) { + print "$plain_text"; + } + elsif (/^[+ ]{$nparents}/) { + print "$file_new"; + } + elsif (/^[- ]{$nparents}/) { + print "$file_old"; + } + else { + print $plain_text; + } + } + elsif (/^--- / || /^\+\+\+ /) { + print $diff_stuff; + } + else { + print "$plain_text"; + } + s/$/$colour{OFF}/; + print "$_"; +} +close INPUTSTREAM; + +sub set_color { + my ($type, $color) = @_; + + $type =~ s/-/_/; + eval "\$$type = \$colour{$color}"; +} @@ -535,7 +535,7 @@ static int socksetup(int port, int **socklist_p) if (set_reuse_addr(sockfd)) { close(sockfd); - return 0; /* not fatal */ + continue; } if (bind(sockfd, ai->ai_addr, ai->ai_addrlen) < 0) { @@ -16,22 +16,6 @@ proc gitdir {} { } } -proc parse_args {rargs} { - global parsed_args - - if {[catch { - set parse_args [concat --default HEAD $rargs] - set parsed_args [split [eval exec git-rev-parse $parse_args] "\n"] - }]} { - # if git-rev-parse failed for some reason... - if {$rargs == {}} { - set rargs HEAD - } - set parsed_args $rargs - } - return $parsed_args -} - proc start_rev_list {rlargs} { global startmsecs nextupdate ncmupdate global commfd leftover tclencoding datemode @@ -46,7 +30,7 @@ proc start_rev_list {rlargs} { } if {[catch { set commfd [open [concat | git-rev-list --header $order \ - --parents --boundary $rlargs] r] + --parents --boundary --default HEAD $rlargs] r] } err]} { puts stderr "Error executing git-rev-list: $err" exit 1 @@ -65,7 +49,7 @@ proc getcommits {rargs} { global phase canv mainfont set phase getcommits - start_rev_list [parse_args $rargs] + start_rev_list $rargs $canv delete all $canv create text 3 3 -anchor nw -text "Reading commits..." \ -font $mainfont -tags textitems diff --git a/rev-parse.c b/rev-parse.c index e956cd5ed5..7f66ae2db8 100644 --- a/rev-parse.c +++ b/rev-parse.c @@ -160,6 +160,14 @@ static int show_file(const char *arg) return 0; } +static void die_badfile(const char *arg) +{ + if (errno != ENOENT) + die("'%s': %s", arg, strerror(errno)); + die("'%s' is ambiguous - revision name or file/directory name?\n" + "Please put '--' before the list of filenames.", arg); +} + int main(int argc, char **argv) { int i, as_is = 0, verify = 0; @@ -176,7 +184,7 @@ int main(int argc, char **argv) if (as_is) { if (show_file(arg) && as_is < 2) if (lstat(arg, &st) < 0) - die("'%s': %s", arg, strerror(errno)); + die_badfile(arg); continue; } if (!strcmp(arg,"-n")) { @@ -343,7 +351,7 @@ int main(int argc, char **argv) if (verify) die("Needed a single revision"); if (lstat(arg, &st) < 0) - die("'%s': %s", arg, strerror(errno)); + die_badfile(arg); } show_default(); if (verify && revs_count != 1) diff --git a/revision.c b/revision.c index 113dd5a89f..f9c7d15f56 100644 --- a/revision.c +++ b/revision.c @@ -789,7 +789,8 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch } if (revs->combine_merges) { revs->ignore_merges = 0; - if (revs->dense_combined_merges) + if (revs->dense_combined_merges && + (revs->diffopt.output_format != DIFF_FORMAT_DIFFSTAT)) revs->diffopt.output_format = DIFF_FORMAT_PATCH; } revs->diffopt.abbrev = revs->abbrev; diff --git a/update-index.c b/update-index.c index 1efac27c6b..facec8d915 100644 --- a/update-index.c +++ b/update-index.c @@ -6,6 +6,7 @@ #include "cache.h" #include "strbuf.h" #include "quote.h" +#include "tree-walk.h" /* * Default to not allowing changes to the list of files. The @@ -328,7 +329,7 @@ static int add_cacheinfo(unsigned int mode, const unsigned char *sha1, return 0; } -static int chmod_path(int flip, const char *path) +static void chmod_path(int flip, const char *path) { int pos; struct cache_entry *ce; @@ -336,21 +337,24 @@ static int chmod_path(int flip, const char *path) pos = cache_name_pos(path, strlen(path)); if (pos < 0) - return -1; + goto fail; ce = active_cache[pos]; mode = ntohl(ce->ce_mode); if (!S_ISREG(mode)) - return -1; + goto fail; switch (flip) { case '+': ce->ce_mode |= htonl(0111); break; case '-': ce->ce_mode &= htonl(~0111); break; default: - return -1; + goto fail; } active_cache_changed = 1; - return 0; + report("chmod %cx '%s'", flip, path); + return; + fail: + die("git-update-index: cannot chmod %cx '%s'", flip, path); } static struct cache_file cache_file; @@ -471,6 +475,124 @@ static void read_index_info(int line_termination) static const char update_index_usage[] = "git-update-index [-q] [--add] [--replace] [--remove] [--unmerged] [--refresh] [--cacheinfo] [--chmod=(+|-)x] [--info-only] [--force-remove] [--stdin] [--index-info] [--ignore-missing] [-z] [--verbose] [--] <file>..."; +static unsigned char head_sha1[20]; +static unsigned char merge_head_sha1[20]; + +static struct cache_entry *read_one_ent(const char *which, + unsigned char *ent, const char *path, + int namelen, int stage) +{ + unsigned mode; + unsigned char sha1[20]; + int size; + struct cache_entry *ce; + + if (get_tree_entry(ent, path, sha1, &mode)) { + error("%s: not in %s branch.", path, which); + return NULL; + } + if (mode == S_IFDIR) { + error("%s: not a blob in %s branch.", path, which); + return NULL; + } + size = cache_entry_size(namelen); + ce = xcalloc(1, size); + + memcpy(ce->sha1, sha1, 20); + memcpy(ce->name, path, namelen); + ce->ce_flags = create_ce_flags(namelen, stage); + ce->ce_mode = create_ce_mode(mode); + return ce; +} + +static int unresolve_one(const char *path) +{ + int namelen = strlen(path); + int pos; + int ret = 0; + struct cache_entry *ce_2 = NULL, *ce_3 = NULL; + + /* See if there is such entry in the index. */ + pos = cache_name_pos(path, namelen); + if (pos < 0) { + /* If there isn't, either it is unmerged, or + * resolved as "removed" by mistake. We do not + * want to do anything in the former case. + */ + pos = -pos-1; + if (pos < active_nr) { + struct cache_entry *ce = active_cache[pos]; + if (ce_namelen(ce) == namelen && + !memcmp(ce->name, path, namelen)) { + fprintf(stderr, + "%s: skipping still unmerged path.\n", + path); + goto free_return; + } + } + } + + /* Grab blobs from given path from HEAD and MERGE_HEAD, + * stuff HEAD version in stage #2, + * stuff MERGE_HEAD version in stage #3. + */ + ce_2 = read_one_ent("our", head_sha1, path, namelen, 2); + ce_3 = read_one_ent("their", merge_head_sha1, path, namelen, 3); + + if (!ce_2 || !ce_3) { + ret = -1; + goto free_return; + } + if (!memcmp(ce_2->sha1, ce_3->sha1, 20) && + ce_2->ce_mode == ce_3->ce_mode) { + fprintf(stderr, "%s: identical in both, skipping.\n", + path); + goto free_return; + } + + remove_file_from_cache(path); + if (add_cache_entry(ce_2, ADD_CACHE_OK_TO_ADD)) { + error("%s: cannot add our version to the index.", path); + ret = -1; + goto free_return; + } + if (!add_cache_entry(ce_3, ADD_CACHE_OK_TO_ADD)) + return 0; + error("%s: cannot add their version to the index.", path); + ret = -1; + free_return: + free(ce_2); + free(ce_3); + return ret; +} + +static void read_head_pointers(void) +{ + if (read_ref(git_path("HEAD"), head_sha1)) + die("No HEAD -- no initial commit yet?\n"); + if (read_ref(git_path("MERGE_HEAD"), merge_head_sha1)) { + fprintf(stderr, "Not in the middle of a merge.\n"); + exit(0); + } +} + +static int do_unresolve(int ac, const char **av) +{ + int i; + int err = 0; + + /* Read HEAD and MERGE_HEAD; if MERGE_HEAD does not exist, we + * are not doing a merge, so exit with success status. + */ + read_head_pointers(); + + for (i = 1; i < ac; i++) { + const char *arg = av[i]; + err |= unresolve_one(arg); + } + return err; +} + int main(int argc, const char **argv) { int i, newfd, entries, has_errors = 0, line_termination = '\n'; @@ -478,6 +600,7 @@ int main(int argc, const char **argv) int read_from_stdin = 0; const char *prefix = setup_git_directory(); int prefix_length = prefix ? strlen(prefix) : 0; + char set_executable_bit = 0; git_config(git_default_config); @@ -544,8 +667,7 @@ int main(int argc, const char **argv) !strcmp(path, "--chmod=+x")) { if (argc <= i+1) die("git-update-index: %s <path>", path); - if (chmod_path(path[8], argv[++i])) - die("git-update-index: %s cannot chmod %s", path, argv[i]); + set_executable_bit = path[8]; continue; } if (!strcmp(path, "--assume-unchanged")) { @@ -581,6 +703,12 @@ int main(int argc, const char **argv) read_index_info(line_termination); break; } + if (!strcmp(path, "--unresolve")) { + has_errors = do_unresolve(argc - i, argv + i); + if (has_errors) + active_cache_changed = 0; + goto finish; + } if (!strcmp(path, "--ignore-missing")) { not_new = 1; continue; @@ -594,6 +722,8 @@ int main(int argc, const char **argv) die("unknown option %s", path); } update_one(path, prefix, prefix_length); + if (set_executable_bit) + chmod_path(set_executable_bit, path); } if (read_from_stdin) { struct strbuf buf; @@ -608,10 +738,16 @@ int main(int argc, const char **argv) else path_name = buf.buf; update_one(path_name, prefix, prefix_length); + if (set_executable_bit) { + const char *p = prefix_path(prefix, prefix_length, path_name); + chmod_path(set_executable_bit, p); + } if (path_name != buf.buf) free(path_name); } } + + finish: if (active_cache_changed) { if (write_cache(newfd, active_cache, active_nr) || commit_index_file(&cache_file)) |