Merge branch 'master' into jc/cache-tree
* master: commit-tree: allow generic object name for the tree as well. Makefile: remove and create xdiff library from scratch. t0000-basic: Add ls-tree recursive test back. Libified diff-index: backward compatibility fix. Libify diff-index. Libify diff-files. Makefile: remove and create libgit.a from scratch. Document the configuration file Document git-var -l listing also configuration variables rev-parse: better error message for ambiguous arguments make update-index --chmod work with multiple files and --stdin socksetup: don't return on set_reuse_addr() error Fix "git show --stat" git-update-index --unresolve Add git-unresolve <paths>... Add colordiff for git to contrib/colordiff. gitk: Let git-rev-list do the argument list parsingmaint
commit
b8ed7f0f40
|
@ -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].
|
|
@ -87,11 +87,11 @@ Given a .git/config like this:
|
||||||
renames = true
|
renames = true
|
||||||
|
|
||||||
; Proxy settings
|
; Proxy settings
|
||||||
[proxy]
|
[core]
|
||||||
command="ssh" for "ssh://kernel.org/"
|
gitproxy="ssh" for "ssh://kernel.org/"
|
||||||
command="proxy-command" for kernel.org
|
gitproxy="proxy-command" for kernel.org
|
||||||
command="myprotocol-command" for "my://"
|
gitproxy="myprotocol-command" for "my://"
|
||||||
command=default-proxy ; for all the rest
|
gitproxy=default-proxy ; for all the rest
|
||||||
|
|
||||||
you can set the filemode to true with
|
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".
|
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.
|
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
|
% 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.
|
you have to provide a regex matching the value of exactly one line.
|
||||||
|
|
||||||
To query the value for a given key, do
|
To query the value for a given key, do
|
||||||
|
@ -133,27 +133,27 @@ or
|
||||||
or, to query a multivar:
|
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:
|
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
|
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,
|
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:
|
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
|
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
|
Author
|
||||||
------
|
------
|
||||||
Written by Johannes Schindelin <Johannes.Schindelin@gmx.de>
|
Written by Johannes Schindelin <Johannes.Schindelin@gmx.de>
|
||||||
|
|
||||||
Documentation
|
Documentation
|
||||||
--------------
|
--------------
|
||||||
Documentation by Johannes Schindelin.
|
Documentation by Johannes Schindelin, Petr Baudis and the git-list <git@vger.kernel.org>.
|
||||||
|
|
||||||
GIT
|
GIT
|
||||||
---
|
---
|
||||||
|
|
|
@ -17,7 +17,9 @@ Prints a git logical variable.
|
||||||
OPTIONS
|
OPTIONS
|
||||||
-------
|
-------
|
||||||
-l::
|
-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
|
EXAMPLE
|
||||||
--------
|
--------
|
||||||
|
@ -46,6 +48,7 @@ See Also
|
||||||
--------
|
--------
|
||||||
gitlink:git-commit-tree[1]
|
gitlink:git-commit-tree[1]
|
||||||
gitlink:git-tag[1]
|
gitlink:git-tag[1]
|
||||||
|
gitlink:git-repo-config[1]
|
||||||
|
|
||||||
Author
|
Author
|
||||||
------
|
------
|
||||||
|
|
6
Makefile
6
Makefile
|
@ -199,7 +199,7 @@ LIB_H = \
|
||||||
tree-walk.h log-tree.h
|
tree-walk.h log-tree.h
|
||||||
|
|
||||||
DIFF_OBJS = \
|
DIFF_OBJS = \
|
||||||
diff-lib.o diffcore-break.o diffcore-order.o \
|
diff.o diff-lib.o diffcore-break.o diffcore-order.o \
|
||||||
diffcore-pickaxe.o diffcore-rename.o tree-diff.o combine-diff.o \
|
diffcore-pickaxe.o diffcore-rename.o tree-diff.o combine-diff.o \
|
||||||
diffcore-delta.o log-tree.o
|
diffcore-delta.o log-tree.o
|
||||||
|
|
||||||
|
@ -575,12 +575,12 @@ $(patsubst git-%$X,%.o,$(PROGRAMS)): $(GITLIBS)
|
||||||
$(DIFF_OBJS): diffcore.h
|
$(DIFF_OBJS): diffcore.h
|
||||||
|
|
||||||
$(LIB_FILE): $(LIB_OBJS)
|
$(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
|
XDIFF_OBJS=xdiff/xdiffi.o xdiff/xprepare.o xdiff/xutils.o xdiff/xemit.o
|
||||||
|
|
||||||
$(XDIFF_LIB): $(XDIFF_OBJS)
|
$(XDIFF_LIB): $(XDIFF_OBJS)
|
||||||
$(AR) rcs $@ $(XDIFF_OBJS)
|
rm -f $@ && $(AR) rcs $@ $(XDIFF_OBJS)
|
||||||
|
|
||||||
|
|
||||||
doc:
|
doc:
|
||||||
|
|
|
@ -92,7 +92,7 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
git_config(git_default_config);
|
git_config(git_default_config);
|
||||||
|
|
||||||
if (argc < 2 || get_sha1_hex(argv[1], tree_sha1) < 0)
|
if (argc < 2 || get_sha1(argv[1], tree_sha1) < 0)
|
||||||
usage(commit_tree_usage);
|
usage(commit_tree_usage);
|
||||||
|
|
||||||
check_valid(tree_sha1, tree_type);
|
check_valid(tree_sha1, tree_type);
|
||||||
|
|
2
config.c
2
config.c
|
@ -252,7 +252,7 @@ int git_default_config(const char *var, const char *value)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add other config variables here.. */
|
/* Add other config variables here and to Documentation/config.txt. */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
This is "colordiff" (http://colordiff.sourceforge.net/) by Dave
|
||||||
|
Ewart <davee@sungate.co.uk>, modified specifically for git.
|
|
@ -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}";
|
||||||
|
}
|
2
daemon.c
2
daemon.c
|
@ -535,7 +535,7 @@ static int socksetup(int port, int **socklist_p)
|
||||||
|
|
||||||
if (set_reuse_addr(sockfd)) {
|
if (set_reuse_addr(sockfd)) {
|
||||||
close(sockfd);
|
close(sockfd);
|
||||||
return 0; /* not fatal */
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bind(sockfd, ai->ai_addr, ai->ai_addrlen) < 0) {
|
if (bind(sockfd, ai->ai_addr, ai->ai_addrlen) < 0) {
|
||||||
|
|
214
diff-files.c
214
diff-files.c
|
@ -12,203 +12,43 @@ static const char diff_files_usage[] =
|
||||||
"git-diff-files [-q] [-0/-1/2/3 |-c|--cc] [<common diff options>] [<path>...]"
|
"git-diff-files [-q] [-0/-1/2/3 |-c|--cc] [<common diff options>] [<path>...]"
|
||||||
COMMON_DIFF_OPTIONS_HELP;
|
COMMON_DIFF_OPTIONS_HELP;
|
||||||
|
|
||||||
static struct rev_info rev;
|
|
||||||
static int silent = 0;
|
|
||||||
static int diff_unmerged_stage = 2;
|
|
||||||
static int combine_merges = 0;
|
|
||||||
static int dense_combined_merges = 0;
|
|
||||||
|
|
||||||
static void show_unmerge(const char *path)
|
|
||||||
{
|
|
||||||
diff_unmerge(&rev.diffopt, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void show_file(int pfx, struct cache_entry *ce)
|
|
||||||
{
|
|
||||||
diff_addremove(&rev.diffopt, pfx, ntohl(ce->ce_mode),
|
|
||||||
ce->sha1, ce->name, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void show_modified(int oldmode, int mode,
|
|
||||||
const unsigned char *old_sha1, const unsigned char *sha1,
|
|
||||||
char *path)
|
|
||||||
{
|
|
||||||
diff_change(&rev.diffopt, oldmode, mode, old_sha1, sha1, path, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, const char **argv)
|
int main(int argc, const char **argv)
|
||||||
{
|
{
|
||||||
const char **pathspec;
|
struct rev_info rev;
|
||||||
const char *prefix = setup_git_directory();
|
int silent = 0;
|
||||||
int entries, i;
|
|
||||||
|
|
||||||
git_config(git_diff_config);
|
git_config(git_diff_config);
|
||||||
diff_setup(&rev.diffopt);
|
init_revisions(&rev);
|
||||||
|
rev.abbrev = 0;
|
||||||
|
|
||||||
|
argc = setup_revisions(argc, argv, &rev, NULL);
|
||||||
while (1 < argc && argv[1][0] == '-') {
|
while (1 < argc && argv[1][0] == '-') {
|
||||||
if (!strcmp(argv[1], "--")) {
|
if (!strcmp(argv[1], "--base"))
|
||||||
argv++;
|
rev.max_count = 1;
|
||||||
argc--;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!strcmp(argv[1], "-0"))
|
|
||||||
diff_unmerged_stage = 0;
|
|
||||||
else if (!strcmp(argv[1], "-1"))
|
|
||||||
diff_unmerged_stage = 1;
|
|
||||||
else if (!strcmp(argv[1], "-2"))
|
|
||||||
diff_unmerged_stage = 2;
|
|
||||||
else if (!strcmp(argv[1], "-3"))
|
|
||||||
diff_unmerged_stage = 3;
|
|
||||||
else if (!strcmp(argv[1], "--base"))
|
|
||||||
diff_unmerged_stage = 1;
|
|
||||||
else if (!strcmp(argv[1], "--ours"))
|
else if (!strcmp(argv[1], "--ours"))
|
||||||
diff_unmerged_stage = 2;
|
rev.max_count = 2;
|
||||||
else if (!strcmp(argv[1], "--theirs"))
|
else if (!strcmp(argv[1], "--theirs"))
|
||||||
diff_unmerged_stage = 3;
|
rev.max_count = 3;
|
||||||
else if (!strcmp(argv[1], "-q"))
|
else if (!strcmp(argv[1], "-q"))
|
||||||
silent = 1;
|
silent = 1;
|
||||||
else if (!strcmp(argv[1], "-r"))
|
else
|
||||||
; /* no-op */
|
usage(diff_files_usage);
|
||||||
else if (!strcmp(argv[1], "-s"))
|
|
||||||
; /* no-op */
|
|
||||||
else if (!strcmp(argv[1], "-c"))
|
|
||||||
combine_merges = 1;
|
|
||||||
else if (!strcmp(argv[1], "--cc"))
|
|
||||||
dense_combined_merges = combine_merges = 1;
|
|
||||||
else {
|
|
||||||
int diff_opt_cnt;
|
|
||||||
diff_opt_cnt = diff_opt_parse(&rev.diffopt,
|
|
||||||
argv+1, argc-1);
|
|
||||||
if (diff_opt_cnt < 0)
|
|
||||||
usage(diff_files_usage);
|
|
||||||
else if (diff_opt_cnt) {
|
|
||||||
argv += diff_opt_cnt;
|
|
||||||
argc -= diff_opt_cnt;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
usage(diff_files_usage);
|
|
||||||
}
|
|
||||||
argv++; argc--;
|
argv++; argc--;
|
||||||
}
|
}
|
||||||
if (dense_combined_merges)
|
/*
|
||||||
rev.diffopt.output_format = DIFF_FORMAT_PATCH;
|
* Make sure there are NO revision (i.e. pending object) parameter,
|
||||||
|
* rev.max_count is reasonable (0 <= n <= 3),
|
||||||
/* Find the directory, and set up the pathspec */
|
* there is no other revision filtering parameters.
|
||||||
pathspec = get_pathspec(prefix, argv + 1);
|
|
||||||
entries = read_cache();
|
|
||||||
|
|
||||||
if (diff_setup_done(&rev.diffopt) < 0)
|
|
||||||
usage(diff_files_usage);
|
|
||||||
|
|
||||||
/* At this point, if argc == 1, then we are doing everything.
|
|
||||||
* Otherwise argv[1] .. argv[argc-1] have the explicit paths.
|
|
||||||
*/
|
*/
|
||||||
if (entries < 0) {
|
if (rev.pending_objects ||
|
||||||
perror("read_cache");
|
rev.min_age != -1 || rev.max_age != -1)
|
||||||
exit(1);
|
usage(diff_files_usage);
|
||||||
}
|
/*
|
||||||
|
* Backward compatibility wart - "diff-files -s" used to
|
||||||
for (i = 0; i < entries; i++) {
|
* defeat the common diff option "-s" which asked for
|
||||||
struct stat st;
|
* DIFF_FORMAT_NO_OUTPUT.
|
||||||
unsigned int oldmode, newmode;
|
*/
|
||||||
struct cache_entry *ce = active_cache[i];
|
if (rev.diffopt.output_format == DIFF_FORMAT_NO_OUTPUT)
|
||||||
int changed;
|
rev.diffopt.output_format = DIFF_FORMAT_RAW;
|
||||||
|
return run_diff_files(&rev, silent);
|
||||||
if (!ce_path_match(ce, pathspec))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (ce_stage(ce)) {
|
|
||||||
struct {
|
|
||||||
struct combine_diff_path p;
|
|
||||||
struct combine_diff_parent filler[5];
|
|
||||||
} combine;
|
|
||||||
int num_compare_stages = 0;
|
|
||||||
|
|
||||||
combine.p.next = NULL;
|
|
||||||
combine.p.len = ce_namelen(ce);
|
|
||||||
combine.p.path = xmalloc(combine.p.len + 1);
|
|
||||||
memcpy(combine.p.path, ce->name, combine.p.len);
|
|
||||||
combine.p.path[combine.p.len] = 0;
|
|
||||||
combine.p.mode = 0;
|
|
||||||
memset(combine.p.sha1, 0, 20);
|
|
||||||
memset(&combine.p.parent[0], 0,
|
|
||||||
sizeof(combine.filler));
|
|
||||||
|
|
||||||
while (i < entries) {
|
|
||||||
struct cache_entry *nce = active_cache[i];
|
|
||||||
int stage;
|
|
||||||
|
|
||||||
if (strcmp(ce->name, nce->name))
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Stage #2 (ours) is the first parent,
|
|
||||||
* stage #3 (theirs) is the second.
|
|
||||||
*/
|
|
||||||
stage = ce_stage(nce);
|
|
||||||
if (2 <= stage) {
|
|
||||||
int mode = ntohl(nce->ce_mode);
|
|
||||||
num_compare_stages++;
|
|
||||||
memcpy(combine.p.parent[stage-2].sha1,
|
|
||||||
nce->sha1, 20);
|
|
||||||
combine.p.parent[stage-2].mode =
|
|
||||||
canon_mode(mode);
|
|
||||||
combine.p.parent[stage-2].status =
|
|
||||||
DIFF_STATUS_MODIFIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* diff against the proper unmerged stage */
|
|
||||||
if (stage == diff_unmerged_stage)
|
|
||||||
ce = nce;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Compensate for loop update
|
|
||||||
*/
|
|
||||||
i--;
|
|
||||||
|
|
||||||
if (combine_merges && num_compare_stages == 2) {
|
|
||||||
show_combined_diff(&combine.p, 2,
|
|
||||||
dense_combined_merges,
|
|
||||||
&rev);
|
|
||||||
free(combine.p.path);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
free(combine.p.path);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Show the diff for the 'ce' if we found the one
|
|
||||||
* from the desired stage.
|
|
||||||
*/
|
|
||||||
show_unmerge(ce->name);
|
|
||||||
if (ce_stage(ce) != diff_unmerged_stage)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lstat(ce->name, &st) < 0) {
|
|
||||||
if (errno != ENOENT && errno != ENOTDIR) {
|
|
||||||
perror(ce->name);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (silent)
|
|
||||||
continue;
|
|
||||||
show_file('-', ce);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
changed = ce_match_stat(ce, &st, 0);
|
|
||||||
if (!changed && !rev.diffopt.find_copies_harder)
|
|
||||||
continue;
|
|
||||||
oldmode = ntohl(ce->ce_mode);
|
|
||||||
|
|
||||||
newmode = canon_mode(st.st_mode);
|
|
||||||
if (!trust_executable_bit &&
|
|
||||||
S_ISREG(newmode) && S_ISREG(oldmode) &&
|
|
||||||
((newmode ^ oldmode) == 0111))
|
|
||||||
newmode = oldmode;
|
|
||||||
show_modified(oldmode, newmode,
|
|
||||||
ce->sha1, (changed ? null_sha1 : ce->sha1),
|
|
||||||
ce->name);
|
|
||||||
}
|
|
||||||
diffcore_std(&rev.diffopt);
|
|
||||||
diff_flush(&rev.diffopt);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
252
diff-index.c
252
diff-index.c
|
@ -1,166 +1,7 @@
|
||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
#include "tree.h"
|
|
||||||
#include "diff.h"
|
#include "diff.h"
|
||||||
|
#include "commit.h"
|
||||||
static int cached_only = 0;
|
#include "revision.h"
|
||||||
static int match_nonexisting = 0;
|
|
||||||
static struct diff_options diff_options;
|
|
||||||
|
|
||||||
/* A file entry went away or appeared */
|
|
||||||
static void show_file(const char *prefix,
|
|
||||||
struct cache_entry *ce,
|
|
||||||
unsigned char *sha1, unsigned int mode)
|
|
||||||
{
|
|
||||||
diff_addremove(&diff_options, prefix[0], ntohl(mode),
|
|
||||||
sha1, ce->name, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int get_stat_data(struct cache_entry *ce,
|
|
||||||
unsigned char ** sha1p, unsigned int *modep)
|
|
||||||
{
|
|
||||||
unsigned char *sha1 = ce->sha1;
|
|
||||||
unsigned int mode = ce->ce_mode;
|
|
||||||
|
|
||||||
if (!cached_only) {
|
|
||||||
static unsigned char no_sha1[20];
|
|
||||||
int changed;
|
|
||||||
struct stat st;
|
|
||||||
if (lstat(ce->name, &st) < 0) {
|
|
||||||
if (errno == ENOENT && match_nonexisting) {
|
|
||||||
*sha1p = sha1;
|
|
||||||
*modep = mode;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
changed = ce_match_stat(ce, &st, 0);
|
|
||||||
if (changed) {
|
|
||||||
mode = create_ce_mode(st.st_mode);
|
|
||||||
if (!trust_executable_bit && S_ISREG(st.st_mode))
|
|
||||||
mode = ce->ce_mode;
|
|
||||||
sha1 = no_sha1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*sha1p = sha1;
|
|
||||||
*modep = mode;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void show_new_file(struct cache_entry *new)
|
|
||||||
{
|
|
||||||
unsigned char *sha1;
|
|
||||||
unsigned int mode;
|
|
||||||
|
|
||||||
/* New file in the index: it might actually be different in
|
|
||||||
* the working copy.
|
|
||||||
*/
|
|
||||||
if (get_stat_data(new, &sha1, &mode) < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
show_file("+", new, sha1, mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int show_modified(struct cache_entry *old,
|
|
||||||
struct cache_entry *new,
|
|
||||||
int report_missing)
|
|
||||||
{
|
|
||||||
unsigned int mode, oldmode;
|
|
||||||
unsigned char *sha1;
|
|
||||||
|
|
||||||
if (get_stat_data(new, &sha1, &mode) < 0) {
|
|
||||||
if (report_missing)
|
|
||||||
show_file("-", old, old->sha1, old->ce_mode);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
oldmode = old->ce_mode;
|
|
||||||
if (mode == oldmode && !memcmp(sha1, old->sha1, 20) &&
|
|
||||||
!diff_options.find_copies_harder)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
mode = ntohl(mode);
|
|
||||||
oldmode = ntohl(oldmode);
|
|
||||||
|
|
||||||
diff_change(&diff_options, oldmode, mode,
|
|
||||||
old->sha1, sha1, old->name, NULL);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int diff_cache(struct cache_entry **ac, int entries, const char **pathspec)
|
|
||||||
{
|
|
||||||
while (entries) {
|
|
||||||
struct cache_entry *ce = *ac;
|
|
||||||
int same = (entries > 1) && ce_same_name(ce, ac[1]);
|
|
||||||
|
|
||||||
if (!ce_path_match(ce, pathspec))
|
|
||||||
goto skip_entry;
|
|
||||||
|
|
||||||
switch (ce_stage(ce)) {
|
|
||||||
case 0:
|
|
||||||
/* No stage 1 entry? That means it's a new file */
|
|
||||||
if (!same) {
|
|
||||||
show_new_file(ce);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* Show difference between old and new */
|
|
||||||
show_modified(ac[1], ce, 1);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
/* No stage 3 (merge) entry? That means it's been deleted */
|
|
||||||
if (!same) {
|
|
||||||
show_file("-", ce, ce->sha1, ce->ce_mode);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* We come here with ce pointing at stage 1
|
|
||||||
* (original tree) and ac[1] pointing at stage
|
|
||||||
* 3 (unmerged). show-modified with
|
|
||||||
* report-missing set to false does not say the
|
|
||||||
* file is deleted but reports true if work
|
|
||||||
* tree does not have it, in which case we
|
|
||||||
* fall through to report the unmerged state.
|
|
||||||
* Otherwise, we show the differences between
|
|
||||||
* the original tree and the work tree.
|
|
||||||
*/
|
|
||||||
if (!cached_only && !show_modified(ce, ac[1], 0))
|
|
||||||
break;
|
|
||||||
/* fallthru */
|
|
||||||
case 3:
|
|
||||||
diff_unmerge(&diff_options, ce->name);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
die("impossible cache entry stage");
|
|
||||||
}
|
|
||||||
|
|
||||||
skip_entry:
|
|
||||||
/*
|
|
||||||
* Ignore all the different stages for this file,
|
|
||||||
* we've handled the relevant cases now.
|
|
||||||
*/
|
|
||||||
do {
|
|
||||||
ac++;
|
|
||||||
entries--;
|
|
||||||
} while (entries && ce_same_name(ce, ac[0]));
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This turns all merge entries into "stage 3". That guarantees that
|
|
||||||
* when we read in the new tree (into "stage 1"), we won't lose sight
|
|
||||||
* of the fact that we had unmerged entries.
|
|
||||||
*/
|
|
||||||
static void mark_merge_entries(void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < active_nr; i++) {
|
|
||||||
struct cache_entry *ce = active_cache[i];
|
|
||||||
if (!ce_stage(ce))
|
|
||||||
continue;
|
|
||||||
ce->ce_flags |= htons(CE_STAGEMASK);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char diff_cache_usage[] =
|
static const char diff_cache_usage[] =
|
||||||
"git-diff-index [-m] [--cached] "
|
"git-diff-index [-m] [--cached] "
|
||||||
|
@ -169,85 +10,30 @@ COMMON_DIFF_OPTIONS_HELP;
|
||||||
|
|
||||||
int main(int argc, const char **argv)
|
int main(int argc, const char **argv)
|
||||||
{
|
{
|
||||||
const char *tree_name = NULL;
|
struct rev_info rev;
|
||||||
unsigned char sha1[20];
|
int match_missing = 0;
|
||||||
const char *prefix = setup_git_directory();
|
int cached = 0;
|
||||||
const char **pathspec = NULL;
|
|
||||||
struct tree *tree;
|
|
||||||
int ret;
|
|
||||||
int allow_options = 1;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
git_config(git_diff_config);
|
git_config(git_diff_config);
|
||||||
diff_setup(&diff_options);
|
init_revisions(&rev);
|
||||||
|
rev.abbrev = 0;
|
||||||
|
|
||||||
|
argc = setup_revisions(argc, argv, &rev, NULL);
|
||||||
for (i = 1; i < argc; i++) {
|
for (i = 1; i < argc; i++) {
|
||||||
const char *arg = argv[i];
|
const char *arg = argv[i];
|
||||||
int diff_opt_cnt;
|
|
||||||
|
|
||||||
if (!allow_options || *arg != '-') {
|
|
||||||
if (tree_name)
|
|
||||||
break;
|
|
||||||
tree_name = arg;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!strcmp(arg, "--")) {
|
if (!strcmp(arg, "--cached"))
|
||||||
allow_options = 0;
|
cached = 1;
|
||||||
continue;
|
else
|
||||||
}
|
|
||||||
if (!strcmp(arg, "-r")) {
|
|
||||||
/* We accept the -r flag just to look like git-diff-tree */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!strcmp(arg, "--cc"))
|
|
||||||
/*
|
|
||||||
* I _think_ "diff-index --cached HEAD" with an
|
|
||||||
* unmerged index could show something else
|
|
||||||
* later, but pretend --cc is the same as -p for
|
|
||||||
* now. "git diff" uses --cc by default.
|
|
||||||
*/
|
|
||||||
argv[i] = arg = "-p";
|
|
||||||
diff_opt_cnt = diff_opt_parse(&diff_options, argv + i,
|
|
||||||
argc - i);
|
|
||||||
if (diff_opt_cnt < 0)
|
|
||||||
usage(diff_cache_usage);
|
usage(diff_cache_usage);
|
||||||
else if (diff_opt_cnt) {
|
|
||||||
i += diff_opt_cnt - 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!strcmp(arg, "-m")) {
|
|
||||||
match_nonexisting = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!strcmp(arg, "--cached")) {
|
|
||||||
cached_only = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
usage(diff_cache_usage);
|
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
pathspec = get_pathspec(prefix, argv + i);
|
* Make sure there is one revision (i.e. pending object),
|
||||||
|
* and there is no revision filtering parameters.
|
||||||
if (diff_setup_done(&diff_options) < 0)
|
*/
|
||||||
|
if (!rev.pending_objects || rev.pending_objects->next ||
|
||||||
|
rev.max_count != -1 || rev.min_age != -1 || rev.max_age != -1)
|
||||||
usage(diff_cache_usage);
|
usage(diff_cache_usage);
|
||||||
|
return run_diff_index(&rev, cached);
|
||||||
if (!tree_name || get_sha1(tree_name, sha1))
|
|
||||||
usage(diff_cache_usage);
|
|
||||||
|
|
||||||
read_cache();
|
|
||||||
|
|
||||||
mark_merge_entries();
|
|
||||||
|
|
||||||
tree = parse_tree_indirect(sha1);
|
|
||||||
if (!tree)
|
|
||||||
die("bad tree object %s", tree_name);
|
|
||||||
if (read_tree(tree, 1, pathspec))
|
|
||||||
die("unable to read tree object %s", tree_name);
|
|
||||||
|
|
||||||
ret = diff_cache(active_cache, active_nr, pathspec);
|
|
||||||
|
|
||||||
diffcore_std(&diff_options);
|
|
||||||
diff_flush(&diff_options);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
2017
diff-lib.c
2017
diff-lib.c
File diff suppressed because it is too large
Load Diff
9
diff.h
9
diff.h
|
@ -28,10 +28,11 @@ struct diff_options {
|
||||||
with_raw:1,
|
with_raw:1,
|
||||||
with_stat:1,
|
with_stat:1,
|
||||||
tree_in_recursive:1,
|
tree_in_recursive:1,
|
||||||
full_index:1;
|
full_index:1,
|
||||||
|
silent_on_remove:1,
|
||||||
|
find_copies_harder:1;
|
||||||
int break_opt;
|
int break_opt;
|
||||||
int detect_rename;
|
int detect_rename;
|
||||||
int find_copies_harder;
|
|
||||||
int line_termination;
|
int line_termination;
|
||||||
int output_format;
|
int output_format;
|
||||||
int pickaxe_opts;
|
int pickaxe_opts;
|
||||||
|
@ -168,4 +169,8 @@ extern void diff_flush(struct diff_options*);
|
||||||
|
|
||||||
extern const char *diff_unique_abbrev(const unsigned char *, int);
|
extern const char *diff_unique_abbrev(const unsigned char *, int);
|
||||||
|
|
||||||
|
extern int run_diff_files(struct rev_info *revs, int silent_on_removed);
|
||||||
|
|
||||||
|
extern int run_diff_index(struct rev_info *revs, int cached);
|
||||||
|
|
||||||
#endif /* DIFF_H */
|
#endif /* DIFF_H */
|
||||||
|
|
20
gitk
20
gitk
|
@ -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} {
|
proc start_rev_list {rlargs} {
|
||||||
global startmsecs nextupdate ncmupdate
|
global startmsecs nextupdate ncmupdate
|
||||||
global commfd leftover tclencoding datemode
|
global commfd leftover tclencoding datemode
|
||||||
|
@ -46,7 +30,7 @@ proc start_rev_list {rlargs} {
|
||||||
}
|
}
|
||||||
if {[catch {
|
if {[catch {
|
||||||
set commfd [open [concat | git-rev-list --header $order \
|
set commfd [open [concat | git-rev-list --header $order \
|
||||||
--parents --boundary $rlargs] r]
|
--parents --boundary --default HEAD $rlargs] r]
|
||||||
} err]} {
|
} err]} {
|
||||||
puts stderr "Error executing git-rev-list: $err"
|
puts stderr "Error executing git-rev-list: $err"
|
||||||
exit 1
|
exit 1
|
||||||
|
@ -65,7 +49,7 @@ proc getcommits {rargs} {
|
||||||
global phase canv mainfont
|
global phase canv mainfont
|
||||||
|
|
||||||
set phase getcommits
|
set phase getcommits
|
||||||
start_rev_list [parse_args $rargs]
|
start_rev_list $rargs
|
||||||
$canv delete all
|
$canv delete all
|
||||||
$canv create text 3 3 -anchor nw -text "Reading commits..." \
|
$canv create text 3 3 -anchor nw -text "Reading commits..." \
|
||||||
-font $mainfont -tags textitems
|
-font $mainfont -tags textitems
|
||||||
|
|
12
rev-parse.c
12
rev-parse.c
|
@ -160,6 +160,14 @@ static int show_file(const char *arg)
|
||||||
return 0;
|
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 main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int i, as_is = 0, verify = 0;
|
int i, as_is = 0, verify = 0;
|
||||||
|
@ -176,7 +184,7 @@ int main(int argc, char **argv)
|
||||||
if (as_is) {
|
if (as_is) {
|
||||||
if (show_file(arg) && as_is < 2)
|
if (show_file(arg) && as_is < 2)
|
||||||
if (lstat(arg, &st) < 0)
|
if (lstat(arg, &st) < 0)
|
||||||
die("'%s': %s", arg, strerror(errno));
|
die_badfile(arg);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!strcmp(arg,"-n")) {
|
if (!strcmp(arg,"-n")) {
|
||||||
|
@ -343,7 +351,7 @@ int main(int argc, char **argv)
|
||||||
if (verify)
|
if (verify)
|
||||||
die("Needed a single revision");
|
die("Needed a single revision");
|
||||||
if (lstat(arg, &st) < 0)
|
if (lstat(arg, &st) < 0)
|
||||||
die("'%s': %s", arg, strerror(errno));
|
die_badfile(arg);
|
||||||
}
|
}
|
||||||
show_default();
|
show_default();
|
||||||
if (verify && revs_count != 1)
|
if (verify && revs_count != 1)
|
||||||
|
|
|
@ -789,7 +789,8 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
|
||||||
}
|
}
|
||||||
if (revs->combine_merges) {
|
if (revs->combine_merges) {
|
||||||
revs->ignore_merges = 0;
|
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.output_format = DIFF_FORMAT_PATCH;
|
||||||
}
|
}
|
||||||
revs->diffopt.abbrev = revs->abbrev;
|
revs->diffopt.abbrev = revs->abbrev;
|
||||||
|
|
|
@ -174,6 +174,27 @@ test_expect_success \
|
||||||
'git-ls-tree -r output for a known tree.' \
|
'git-ls-tree -r output for a known tree.' \
|
||||||
'diff current expected'
|
'diff current expected'
|
||||||
|
|
||||||
|
# But with -r -t we can have both.
|
||||||
|
test_expect_success \
|
||||||
|
'showing tree with git-ls-tree -r -t' \
|
||||||
|
'git-ls-tree -r -t $tree >current'
|
||||||
|
cat >expected <<\EOF
|
||||||
|
100644 blob f87290f8eb2cbbea7857214459a0739927eab154 path0
|
||||||
|
120000 blob 15a98433ae33114b085f3eb3bb03b832b3180a01 path0sym
|
||||||
|
040000 tree 58a09c23e2ca152193f2786e06986b7b6712bdbe path2
|
||||||
|
100644 blob 3feff949ed00a62d9f7af97c15cd8a30595e7ac7 path2/file2
|
||||||
|
120000 blob d8ce161addc5173867a3c3c730924388daedbc38 path2/file2sym
|
||||||
|
040000 tree 21ae8269cacbe57ae09138dcc3a2887f904d02b3 path3
|
||||||
|
100644 blob 0aa34cae68d0878578ad119c86ca2b5ed5b28376 path3/file3
|
||||||
|
120000 blob 8599103969b43aff7e430efea79ca4636466794f path3/file3sym
|
||||||
|
040000 tree 3c5e5399f3a333eddecce7a9b9465b63f65f51e2 path3/subp3
|
||||||
|
100644 blob 00fb5908cb97c2564a9783c0c64087333b3b464f path3/subp3/file3
|
||||||
|
120000 blob 6649a1ebe9e9f1c553b66f5a6e74136a07ccc57c path3/subp3/file3sym
|
||||||
|
EOF
|
||||||
|
test_expect_success \
|
||||||
|
'git-ls-tree -r output for a known tree.' \
|
||||||
|
'diff current expected'
|
||||||
|
|
||||||
################################################################
|
################################################################
|
||||||
rm .git/index
|
rm .git/index
|
||||||
test_expect_success \
|
test_expect_success \
|
||||||
|
|
|
@ -37,7 +37,7 @@ compare_change () {
|
||||||
}
|
}
|
||||||
|
|
||||||
check_cache_at () {
|
check_cache_at () {
|
||||||
clean_if_empty=`git-diff-files "$1"`
|
clean_if_empty=`git-diff-files -- "$1"`
|
||||||
case "$clean_if_empty" in
|
case "$clean_if_empty" in
|
||||||
'') echo "$1: clean" ;;
|
'') echo "$1: clean" ;;
|
||||||
?*) echo "$1: dirty" ;;
|
?*) echo "$1: dirty" ;;
|
||||||
|
|
|
@ -20,7 +20,7 @@ compare_change () {
|
||||||
}
|
}
|
||||||
|
|
||||||
check_cache_at () {
|
check_cache_at () {
|
||||||
clean_if_empty=`git-diff-files "$1"`
|
clean_if_empty=`git-diff-files -- "$1"`
|
||||||
case "$clean_if_empty" in
|
case "$clean_if_empty" in
|
||||||
'') echo "$1: clean" ;;
|
'') echo "$1: clean" ;;
|
||||||
?*) echo "$1: dirty" ;;
|
?*) echo "$1: dirty" ;;
|
||||||
|
|
|
@ -28,7 +28,7 @@ cat >expected <<\EOF
|
||||||
EOF
|
EOF
|
||||||
test_expect_success \
|
test_expect_success \
|
||||||
'limit to path should show nothing' \
|
'limit to path should show nothing' \
|
||||||
'git-diff-index --cached $tree path >current &&
|
'git-diff-index --cached $tree -- path >current &&
|
||||||
compare_diff_raw current expected'
|
compare_diff_raw current expected'
|
||||||
|
|
||||||
cat >expected <<\EOF
|
cat >expected <<\EOF
|
||||||
|
@ -36,7 +36,7 @@ cat >expected <<\EOF
|
||||||
EOF
|
EOF
|
||||||
test_expect_success \
|
test_expect_success \
|
||||||
'limit to path1 should show path1/file1' \
|
'limit to path1 should show path1/file1' \
|
||||||
'git-diff-index --cached $tree path1 >current &&
|
'git-diff-index --cached $tree -- path1 >current &&
|
||||||
compare_diff_raw current expected'
|
compare_diff_raw current expected'
|
||||||
|
|
||||||
cat >expected <<\EOF
|
cat >expected <<\EOF
|
||||||
|
@ -44,7 +44,7 @@ cat >expected <<\EOF
|
||||||
EOF
|
EOF
|
||||||
test_expect_success \
|
test_expect_success \
|
||||||
'limit to path1/ should show path1/file1' \
|
'limit to path1/ should show path1/file1' \
|
||||||
'git-diff-index --cached $tree path1/ >current &&
|
'git-diff-index --cached $tree -- path1/ >current &&
|
||||||
compare_diff_raw current expected'
|
compare_diff_raw current expected'
|
||||||
|
|
||||||
cat >expected <<\EOF
|
cat >expected <<\EOF
|
||||||
|
@ -52,14 +52,14 @@ cat >expected <<\EOF
|
||||||
EOF
|
EOF
|
||||||
test_expect_success \
|
test_expect_success \
|
||||||
'limit to file0 should show file0' \
|
'limit to file0 should show file0' \
|
||||||
'git-diff-index --cached $tree file0 >current &&
|
'git-diff-index --cached $tree -- file0 >current &&
|
||||||
compare_diff_raw current expected'
|
compare_diff_raw current expected'
|
||||||
|
|
||||||
cat >expected <<\EOF
|
cat >expected <<\EOF
|
||||||
EOF
|
EOF
|
||||||
test_expect_success \
|
test_expect_success \
|
||||||
'limit to file0/ should emit nothing.' \
|
'limit to file0/ should emit nothing.' \
|
||||||
'git-diff-index --cached $tree file0/ >current &&
|
'git-diff-index --cached $tree -- file0/ >current &&
|
||||||
compare_diff_raw current expected'
|
compare_diff_raw current expected'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
|
150
update-index.c
150
update-index.c
|
@ -7,6 +7,7 @@
|
||||||
#include "strbuf.h"
|
#include "strbuf.h"
|
||||||
#include "quote.h"
|
#include "quote.h"
|
||||||
#include "cache-tree.h"
|
#include "cache-tree.h"
|
||||||
|
#include "tree-walk.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Default to not allowing changes to the list of files. The
|
* Default to not allowing changes to the list of files. The
|
||||||
|
@ -337,7 +338,7 @@ static int add_cacheinfo(unsigned int mode, const unsigned char *sha1,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int chmod_path(int flip, const char *path)
|
static void chmod_path(int flip, const char *path)
|
||||||
{
|
{
|
||||||
int pos;
|
int pos;
|
||||||
struct cache_entry *ce;
|
struct cache_entry *ce;
|
||||||
|
@ -345,22 +346,25 @@ static int chmod_path(int flip, const char *path)
|
||||||
|
|
||||||
pos = cache_name_pos(path, strlen(path));
|
pos = cache_name_pos(path, strlen(path));
|
||||||
if (pos < 0)
|
if (pos < 0)
|
||||||
return -1;
|
goto fail;
|
||||||
ce = active_cache[pos];
|
ce = active_cache[pos];
|
||||||
mode = ntohl(ce->ce_mode);
|
mode = ntohl(ce->ce_mode);
|
||||||
if (!S_ISREG(mode))
|
if (!S_ISREG(mode))
|
||||||
return -1;
|
goto fail;
|
||||||
switch (flip) {
|
switch (flip) {
|
||||||
case '+':
|
case '+':
|
||||||
ce->ce_mode |= htonl(0111); break;
|
ce->ce_mode |= htonl(0111); break;
|
||||||
case '-':
|
case '-':
|
||||||
ce->ce_mode &= htonl(~0111); break;
|
ce->ce_mode &= htonl(~0111); break;
|
||||||
default:
|
default:
|
||||||
return -1;
|
goto fail;
|
||||||
}
|
}
|
||||||
cache_tree_invalidate_path(active_cache_tree, path);
|
cache_tree_invalidate_path(active_cache_tree, path);
|
||||||
active_cache_changed = 1;
|
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;
|
static struct cache_file cache_file;
|
||||||
|
@ -483,6 +487,124 @@ static void read_index_info(int line_termination)
|
||||||
static const char update_index_usage[] =
|
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>...";
|
"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 main(int argc, const char **argv)
|
||||||
{
|
{
|
||||||
int i, newfd, entries, has_errors = 0, line_termination = '\n';
|
int i, newfd, entries, has_errors = 0, line_termination = '\n';
|
||||||
|
@ -490,6 +612,7 @@ int main(int argc, const char **argv)
|
||||||
int read_from_stdin = 0;
|
int read_from_stdin = 0;
|
||||||
const char *prefix = setup_git_directory();
|
const char *prefix = setup_git_directory();
|
||||||
int prefix_length = prefix ? strlen(prefix) : 0;
|
int prefix_length = prefix ? strlen(prefix) : 0;
|
||||||
|
char set_executable_bit = 0;
|
||||||
|
|
||||||
git_config(git_default_config);
|
git_config(git_default_config);
|
||||||
|
|
||||||
|
@ -556,8 +679,7 @@ int main(int argc, const char **argv)
|
||||||
!strcmp(path, "--chmod=+x")) {
|
!strcmp(path, "--chmod=+x")) {
|
||||||
if (argc <= i+1)
|
if (argc <= i+1)
|
||||||
die("git-update-index: %s <path>", path);
|
die("git-update-index: %s <path>", path);
|
||||||
if (chmod_path(path[8], argv[++i]))
|
set_executable_bit = path[8];
|
||||||
die("git-update-index: %s cannot chmod %s", path, argv[i]);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!strcmp(path, "--assume-unchanged")) {
|
if (!strcmp(path, "--assume-unchanged")) {
|
||||||
|
@ -593,6 +715,12 @@ int main(int argc, const char **argv)
|
||||||
read_index_info(line_termination);
|
read_index_info(line_termination);
|
||||||
break;
|
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")) {
|
if (!strcmp(path, "--ignore-missing")) {
|
||||||
not_new = 1;
|
not_new = 1;
|
||||||
continue;
|
continue;
|
||||||
|
@ -606,6 +734,8 @@ int main(int argc, const char **argv)
|
||||||
die("unknown option %s", path);
|
die("unknown option %s", path);
|
||||||
}
|
}
|
||||||
update_one(path, prefix, prefix_length);
|
update_one(path, prefix, prefix_length);
|
||||||
|
if (set_executable_bit)
|
||||||
|
chmod_path(set_executable_bit, path);
|
||||||
}
|
}
|
||||||
if (read_from_stdin) {
|
if (read_from_stdin) {
|
||||||
struct strbuf buf;
|
struct strbuf buf;
|
||||||
|
@ -620,10 +750,16 @@ int main(int argc, const char **argv)
|
||||||
else
|
else
|
||||||
path_name = buf.buf;
|
path_name = buf.buf;
|
||||||
update_one(path_name, prefix, prefix_length);
|
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)
|
if (path_name != buf.buf)
|
||||||
free(path_name);
|
free(path_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
finish:
|
||||||
if (active_cache_changed) {
|
if (active_cache_changed) {
|
||||||
if (write_cache(newfd, active_cache, active_nr) ||
|
if (write_cache(newfd, active_cache, active_nr) ||
|
||||||
commit_index_file(&cache_file))
|
commit_index_file(&cache_file))
|
||||||
|
|
Loading…
Reference in New Issue