*.xml
*.html
-*.1
-*.7
+*.[1-8]
*.made
howto-index.txt
doc.dep
branch.<name>.merge to the desired branch, and use the special setting
`.` (a period) for branch.<name>.remote.
+clean.requireForce::
+ A boolean to make git-clean do nothing unless given -f or -n. Defaults
+ to false.
+
color.branch::
A boolean to enable/disable color in the output of
gitlink:git-branch[1]. May be set to `true` (or `always`),
SYNOPSIS
--------
[verse]
-'git-checkout' [-q] [-f] [-b [--track | --no-track] <new_branch> [-l]] [-m] [<branch>]
+'git-checkout' [-q] [-f] [[--track | --no-track] -b <new_branch> [-l]] [-m] [<branch>]
'git-checkout' [<tree-ish>] <paths>...
DESCRIPTION
SYNOPSIS
--------
[verse]
-'git-clean' [-d] [-n] [-q] [-x | -X] [--] <paths>...
+'git-clean' [-d] [-f] [-n] [-q] [-x | -X] [--] <paths>...
DESCRIPTION
-----------
-d::
Remove untracked directories in addition to untracked files.
+-f::
+ If the git configuration specifies clean.forceRequire as true,
+ git-clean will refuse to run unless given -f or -n.
+
-n::
Don't actually remove anything, just show what would be done.
<3> "reset" copies the old head to .git/ORIG_HEAD; redo the
commit by starting with its log message. If you do not need to
edit the message further, you can give -C option instead.
++
+See also the --amend option to gitlink:git-commit[1].
Undo commits permanently::
+
Unspecified::
No glob pattern matches the path, and nothing says if
- the path has or does not have the attribute.
+ the path has or does not have the attribute, the
+ attribute for the path is said to be Unspecified.
When more than one glob pattern matches the path, a later line
-overrides an earlier line.
+overrides an earlier line. This overriding is done per
+attribute.
When deciding what attributes are assigned to a path, git
consults `$GIT_DIR/info/attributes` file (which has the highest
text, it is treated as text. Otherwise it would
generate `Binary files differ`.
-Any other value set to `diff` attribute is ignored and git acts
-as if the attribute is left unspecified.
+String::
+
+ Diff is shown using the specified custom diff driver.
+ The driver program is given its input using the same
+ calling convention as used for GIT_EXTERNAL_DIFF
+ program.
+
+
+Defining a custom diff driver
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The definition of a diff driver is done in `gitconfig`, not
+`gitattributes` file, so strictly speaking this manual page is a
+wrong place to talk about it. However...
+
+To define a custom diff driver `jcdiff`, add a section to your
+`$GIT_DIR/config` file (or `$HOME/.gitconfig` file) like this:
+
+----------------------------------------------------------------
+[diff "jcdiff"]
+ command = j-c-diff
+----------------------------------------------------------------
+
+When git needs to show you a diff for the path with `diff`
+attribute set to `jcdiff`, it calls the command you specified
+with the above configuration, i.e. `j-c-diff`, with 7
+parameters, just like `GIT_EXTERNAL_DIFF` program is called.
+See gitlink:git[7] for details.
Performing a three-way merge
different merge driver to be used for paths to which the
`merge` attribute is unspecified.
-Any other string value::
+String::
3-way merge is performed using the specified custom
merge driver. The built-in 3-way merge driver can be
explicitly specified by asking for "text" driver; the
built-in "take the current branch" driver can be
- requested by "binary".
+ requested with "binary".
Defining a custom merge driver
bindir = $(prefix)/bin
gitexecdir = $(bindir)
template_dir = $(prefix)/share/git-core/templates/
-ETC_GITCONFIG = $(prefix)/etc/gitconfig
+ifeq ($(prefix),/usr)
+sysconfdir = /etc
+else
+sysconfdir = $(prefix)/etc
+endif
+ETC_GITCONFIG = $(sysconfdir)/gitconfig
# DESTDIR=
# default configuration for gitweb
GITWEB_SITE_HEADER =
GITWEB_SITE_FOOTER =
-export prefix bindir gitexecdir template_dir
+export prefix bindir gitexecdir template_dir sysconfdir
CC = gcc
AR = ar
#include "log-tree.h"
#include "builtin.h"
-/* NEEDSWORK: struct object has place for name but we _do_
- * know mode when we extracted the blob out of a tree, which
- * we currently lose.
- */
struct blobinfo {
unsigned char sha1[20];
const char *name;
+ unsigned mode;
};
static const char builtin_diff_usage[] =
struct diff_filespec *one, *two;
if (!is_null_sha1(old_sha1) && !is_null_sha1(new_sha1) &&
- !hashcmp(old_sha1, new_sha1))
+ !hashcmp(old_sha1, new_sha1) && (old_mode == new_mode))
return;
if (opt->reverse_diff) {
die("'%s': %s", path, strerror(errno));
if (!(S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)))
die("'%s': not a regular file or symlink", path);
+
+ if (blob[0].mode == S_IFINVALID)
+ blob[0].mode = canon_mode(st.st_mode);
+
stuff_change(&revs->diffopt,
- canon_mode(st.st_mode), canon_mode(st.st_mode),
+ blob[0].mode, canon_mode(st.st_mode),
blob[0].sha1, null_sha1,
path, path);
diffcore_std(&revs->diffopt);
if (argc > 1)
usage(builtin_diff_usage);
+ if (blob[0].mode == S_IFINVALID)
+ blob[0].mode = mode;
+
+ if (blob[1].mode == S_IFINVALID)
+ blob[1].mode = mode;
+
stuff_change(&revs->diffopt,
- mode, mode,
+ blob[0].mode, blob[1].mode,
blob[0].sha1, blob[1].sha1,
blob[0].name, blob[1].name);
diffcore_std(&revs->diffopt);
die("more than two blobs given: '%s'", name);
hashcpy(blob[blobs].sha1, obj->sha1);
blob[blobs].name = name;
+ blob[blobs].mode = list->mode;
blobs++;
continue;
return parse_reflist(reflist);
}
if (!strcmp("pick-rref", argv[1])) {
+ const char *ls_remote_result;
if (argc != 4)
return error("pick-rref takes 2 args");
- return pick_rref(sopt, argv[2], argv[3]);
+ ls_remote_result = argv[3];
+ if (!strcmp(ls_remote_result, "-"))
+ ls_remote_result = get_stdin();
+ return pick_rref(sopt, argv[2], ls_remote_result);
}
if (!strcmp("expand-refs-wildcard", argv[1])) {
const char *reflist;
#define DTYPE(de) DT_UNKNOWN
#endif
+/* unknown mode (impossible combination S_IFIFO|S_IFCHR) */
+#define S_IFINVALID 0030000
+
/*
* A "directory link" is a link to another git directory.
*
#define DEFAULT_ABBREV 7
extern int get_sha1(const char *str, unsigned char *sha1);
+extern int get_sha1_with_mode(const char *str, unsigned char *sha1, unsigned *mode);
extern int get_sha1_hex(const char *hex, unsigned char *sha1);
extern char *sha1_to_hex(const unsigned char *sha1); /* static buffer result! */
extern int read_ref(const char *filename, unsigned char *sha1);
core.legacyHeaders
core.packedGitWindowSize
core.packedGitLimit
+ clean.requireForce
color.branch
color.branch.current
color.branch.local
}
print FI "\n";
- my $path = "$prefix$name";
+ my $path;
+ if ($prefix) {
+ $path = "$prefix/$name";
+ } else {
+ $path = "$name";
+ }
$files{$path} = [$next_mark++, $mode];
$commit_time = $mtime if $mtime > $commit_time;
prefix = slash - path + 1;
while ((next = *++pathspec) != NULL) {
int len = strlen(next);
- if (len >= prefix && !memcmp(path, next, len))
+ if (len >= prefix && !memcmp(path, next, prefix))
continue;
+ len = prefix - 1;
for (;;) {
if (!len)
return 0;
buf = xmalloc(buf_sz);
for (;;) {
- size_t n = xread(pack_fd, buf, buf_sz);
+ ssize_t n = xread(pack_fd, buf, buf_sz);
if (!n)
break;
if (n < 0)
if (e->offset) {
duplicate_count_by_type[type]++;
return 1;
+ } else if (find_sha1_pack(sha1, packed_git)) {
+ e->type = type;
+ e->pack_id = MAX_PACK_ID;
+ e->offset = 1; /* just not zero! */
+ duplicate_count_by_type[type]++;
+ return 1;
}
if (last && last->data && last->depth < max_depth) {
e = insert_object(sha1);
e->type = type;
e->pack_id = MAX_PACK_ID;
+ e->offset = 1; /* just not zero! */
}
insert_mark(mark, e);
}
if (i != argc)
usage(fast_import_usage);
+ prepare_packed_git();
start_packfile();
for (;;) {
read_next_command();
<"$dotest/$msgnum" >"$dotest/info" ||
stop_here $this
test -s $dotest/patch || {
- echo "Patch is empty. Was is split wrong?"
+ echo "Patch is empty. Was it split wrong?"
stop_here $this
}
git-stripspace < "$dotest/msg" > "$dotest/msg-clean"
git-mailinfo $keep_subject $utf8 \
.dotest/msg .dotest/patch <$i >.dotest/info || exit 1
test -s .dotest/patch || {
- echo "Patch is empty. Was is split wrong?"
+ echo "Patch is empty. Was it split wrong?"
exit 1
}
git-stripspace < .dotest/msg > .dotest/msg-clean
newbranch_log=
merge=
quiet=
+v=-v
LF='
'
while [ "$#" != "0" ]; do
;;
"-q")
quiet=1
+ v=
;;
--)
break
if [ "$force" ]
then
- git-read-tree --reset -u $new
+ git-read-tree $v --reset -u $new
else
git-update-index --refresh >/dev/null
merge_error=$(git-read-tree -m -u --exclude-per-directory=.gitignore $old $new 2>&1) || (
# Match the index to the working tree, and do a three-way.
git diff-files --name-only | git update-index --remove --stdin &&
work=`git write-tree` &&
- git read-tree --reset -u $new || exit
+ git read-tree $v --reset -u $new || exit
eval GITHEAD_$new='${new_name:-${branch:-$new}}' &&
eval GITHEAD_$work=local &&
# this is not a real merge before committing, but just carrying
# the working tree changes along.
unmerged=`git ls-files -u`
- git read-tree --reset $new
+ git read-tree $v --reset $new
case "$unmerged" in
'') ;;
*)
# Copyright (c) 2005-2006 Pavel Roskin
#
-USAGE="[-d] [-n] [-q] [-x | -X] [--] <paths>..."
+USAGE="[-d] [-f] [-n] [-q] [-x | -X] [--] <paths>..."
LONG_USAGE='Clean untracked files from the working directory
-d remove directories as well
+ -f override clean.requireForce and clean anyway
-n don'\''t remove anything, just show what would be done
-q be quiet, only report errors
-x remove ignored files as well
ignored=
ignoredonly=
cleandir=
+disabled="`git-config --bool clean.requireForce`"
rmf="rm -f --"
rmrf="rm -rf --"
rm_refuse="echo Not removing"
-d)
cleandir=1
;;
+ -f)
+ disabled=
+ ;;
-n)
+ disabled=
rmf="echo Would remove"
rmrf="echo Would remove"
rm_refuse="echo Would not remove"
shift
done
+if [ "$disabled" = true ]; then
+ echo "clean.requireForce set and -n or -f not given; refusing to clean"
+ exit 1
+fi
+
case "$ignored,$ignoredonly" in
1,1) usage;;
esac
# See if all of what we are going to fetch are
# connected to our repository's tips, in which
# case we do not have to do any fetch.
- theirs=$(git-fetch--tool -s pick-rref \
- "$rref" "$ls_remote_result") &&
+ theirs=$(echo "$ls_remote_result" | \
+ git-fetch--tool -s pick-rref "$rref" "-") &&
# This will barf when $theirs reach an object that
# we do not have in our repository. Otherwise,
git-rev-list --objects $theirs --not --all \
>/dev/null 2>/dev/null
then
- git-fetch--tool pick-rref "$rref" "$ls_remote_result"
+ echo "$ls_remote_result" | \
+ git-fetch--tool pick-rref "$rref" "-"
else
git-fetch-pack --thin $exec $keep $shallow_depth \
$quiet $no_progress "$remote" $rref ||
fi
# Find $remote_name from ls-remote output.
- head=$(git-fetch--tool -s pick-rref \
- "$remote_name" "$ls_remote_result")
+ head=$(echo "$ls_remote_result" | \
+ git-fetch--tool -s pick-rref "$remote_name" "-")
expr "z$head" : "z$_x40\$" >/dev/null ||
die "No such ref $remote_name at $remote"
echo >&2 "Fetching $remote_name from $remote using $proto"
echo $patch_name
(cat $QUILT_PATCHES/$patch_name | git-mailinfo "$tmp_msg" "$tmp_patch" > "$tmp_info") || exit 3
test -s .dotest/patch || {
- echo "Patch is empty. Was is split wrong?"
+ echo "Patch is empty. Was it split wrong?"
exit 1
}
die "Cannot do a soft reset in the middle of a merge."
fi
else
- git-read-tree --reset $update "$rev" || exit
+ git-read-tree -v --reset $update "$rev" || exit
fi
# Any resets update HEAD to the head being switched to.
} elsif ($self->use_svnsync_props) {
my $full_url = $self->svnsync->{url};
$full_url .= "/$self->{path}" if length $self->{path};
+ remove_username($full_url);
my $uuid = $self->svnsync->{uuid};
$log_entry{metadata} = "$full_url\@$rev $uuid";
$email ||= "$author\@$uuid"
} else {
- $log_entry{metadata} = $self->metadata_url. "\@$rev " .
+ my $url = $self->metadata_url;
+ remove_username($url);
+ $log_entry{metadata} = "$url\@$rev " .
$self->ra->get_uuid;
$email ||= "$author\@" . $self->ra->get_uuid;
}
%build
make %{_smp_mflags} CFLAGS="$RPM_OPT_FLAGS" WITH_P4IMPORT=YesPlease \
+ ETC_GITCONFIG=/etc/gitconfig \
prefix=%{_prefix} PYTHON_PATH=%{python_path} all %{!?_without_docs: doc}
%install
rm -rf $RPM_BUILD_ROOT
make %{_smp_mflags} CFLAGS="$RPM_OPT_FLAGS" DESTDIR=$RPM_BUILD_ROOT \
WITH_P4IMPORT=YesPlease prefix=%{_prefix} mandir=%{_mandir} \
+ ETC_GITCONFIG=/etc/gitconfig \
PYTHON_PATH=%{python_path} \
INSTALLDIRS=vendor install %{!?_without_docs: install-doc}
find $RPM_BUILD_ROOT -type f -name .packlist -exec rm -f {} ';'
}
void add_object_array(struct object *obj, const char *name, struct object_array *array)
+{
+ add_object_array_with_mode(obj, name, array, S_IFINVALID);
+}
+
+void add_object_array_with_mode(struct object *obj, const char *name, struct object_array *array, unsigned mode)
{
unsigned nr = array->nr;
unsigned alloc = array->alloc;
}
objects[nr].item = obj;
objects[nr].name = name;
+ objects[nr].mode = mode;
array->nr = ++nr;
}
struct object_array_entry {
struct object *item;
const char *name;
+ unsigned mode;
} *objects;
};
/* Object array handling .. */
void add_object_array(struct object *obj, const char *name, struct object_array *array);
+void add_object_array_with_mode(struct object *obj, const char *name, struct object_array *array, unsigned mode);
#endif /* OBJECT_H */
}
void add_pending_object(struct rev_info *revs, struct object *obj, const char *name)
+{
+ add_pending_object_with_mode(revs, obj, name, S_IFINVALID);
+}
+
+void add_pending_object_with_mode(struct rev_info *revs, struct object *obj, const char *name, unsigned mode)
{
if (revs->no_walk && (obj->flags & UNINTERESTING))
die("object ranges do not make sense when not walking revisions");
- add_object_array(obj, name, &revs->pending);
+ add_object_array_with_mode(obj, name, &revs->pending, mode);
if (revs->reflog_info && obj->type == OBJ_COMMIT)
add_reflog_for_walk(revs->reflog_info,
(struct commit *)obj, name);
int flags,
int cant_be_filename)
{
+ unsigned mode;
char *dotdot;
struct object *object;
unsigned char sha1[20];
local_flags = UNINTERESTING;
arg++;
}
- if (get_sha1(arg, sha1))
+ if (get_sha1_with_mode(arg, sha1, &mode))
return -1;
if (!cant_be_filename)
verify_non_filename(revs->prefix, arg);
object = get_reference(revs, arg, sha1, flags ^ local_flags);
- add_pending_object(revs, object, arg);
+ add_pending_object_with_mode(revs, object, arg, mode);
return 0;
}
if (def && !revs->pending.nr) {
unsigned char sha1[20];
struct object *object;
- if (get_sha1(def, sha1))
+ unsigned mode;
+ if (get_sha1_with_mode(def, sha1, &mode))
die("bad default revision '%s'", def);
object = get_reference(revs, def, sha1, 0);
- add_pending_object(revs, object, def);
+ add_pending_object_with_mode(revs, object, def, mode);
}
if (revs->topo_order)
const char *name);
extern void add_pending_object(struct rev_info *revs, struct object *obj, const char *name);
+extern void add_pending_object_with_mode(struct rev_info *revs, struct object *obj, const char *name, unsigned mode);
#endif
*/
int get_sha1(const char *name, unsigned char *sha1)
{
- int ret, bracket_depth;
unsigned unused;
+ return get_sha1_with_mode(name, sha1, &unused);
+}
+
+int get_sha1_with_mode(const char *name, unsigned char *sha1, unsigned *mode)
+{
+ int ret, bracket_depth;
int namelen = strlen(name);
const char *cp;
+ *mode = S_IFINVALID;
prepare_alt_odb();
ret = get_sha1_1(name, namelen, sha1);
if (!ret)
break;
if (ce_stage(ce) == stage) {
hashcpy(sha1, ce->sha1);
+ *mode = ntohl(ce->ce_mode);
return 0;
}
pos++;
unsigned char tree_sha1[20];
if (!get_sha1_1(name, cp-name, tree_sha1))
return get_tree_entry(tree_sha1, cp+1, sha1,
- &unused);
+ mode);
}
return ret;
}
git-ls-files --error-unmatch d.ig/d.if d.ig/d.ig
'
+mkdir 1 1/2 1/3
+touch 1/2/a 1/3/b 1/2/c
+test_expect_success 'check correct prefix detection' '
+ git add 1/2/a 1/3/b 1/2/c
+'
+
test_done
git update-ref HEAD $commit
echo 2 > a1
-git commit -m "This is a very, very long first line for the commit message to see if it is wrapped correctly" a1
+git commit --quiet -m "This is a very, very long first line for the commit message to see if it is wrapped correctly" a1
# test if the wrapping is still valid when replacing all i's by treble clefs.
echo 3 > a1
-git commit -m "$(echo "This is a very, very long first line for the commit message to see if it is wrapped correctly" | sed "s/i/1234/g" | tr 1234 '\360\235\204\236')" a1
+git commit --quiet -m "$(echo "This is a very, very long first line for the commit message to see if it is wrapped correctly" | sed "s/i/1234/g" | tr 1234 '\360\235\204\236')" a1
# now fsck up the utf8
git repo-config i18n.commitencoding non-utf-8
echo 4 > a1
-git commit -m "$(echo "This is a very, very long first line for the commit message to see if it is wrapped correctly" | sed "s/i/1234/g" | tr 1234 '\370\235\204\236')" a1
+git commit --quiet -m "$(echo "This is a very, very long first line for the commit message to see if it is wrapped correctly" | sed "s/i/1234/g" | tr 1234 '\370\235\204\236')" a1
echo 5 > a1
-git commit -m "a 12 34 56 78" a1
+git commit --quiet -m "a 12 34 56 78" a1
git shortlog -w HEAD > out
test-genrandom "$i" 8192 >>file_$i &&
git-update-index --add file_$i || return 1
done &&
- echo 101 >file_101 && tail -c 8192 file_100 >>file_101 &&
+ { echo 101 && test-genrandom 100 8192; } >file_101 &&
git-update-index --add file_101 &&
tree=`git-write-tree` &&
commit=`git-commit-tree $tree </dev/null` && {
MSG="Create file <$_file> with <$_line> inside."
fi
- git-commit -m "$MSG" $_file
+ test_tick
+ git-commit --quiet -m "$MSG" $_file
}
HASH1=
+HASH2=
HASH3=
HASH4=
-test_expect_success \
- 'set up basic repo with 1 file (hello) and 4 commits' \
- 'add_line_into_file "1: Hello World" hello &&
+test_expect_success 'set up basic repo with 1 file (hello) and 4 commits' '
+ add_line_into_file "1: Hello World" hello &&
+ HASH1=$(git rev-parse --verify HEAD) &&
add_line_into_file "2: A new day for git" hello &&
+ HASH2=$(git rev-parse --verify HEAD) &&
add_line_into_file "3: Another new day for git" hello &&
+ HASH3=$(git rev-parse --verify HEAD) &&
add_line_into_file "4: Ciao for now" hello &&
- HASH1=$(git rev-list HEAD | tail -1) &&
- HASH3=$(git rev-list HEAD | head -2 | tail -1) &&
- HASH4=$(git rev-list HEAD | head -1)'
+ HASH4=$(git rev-parse --verify HEAD)
+'
test_expect_success 'bisect starts with only one bad' '
git bisect reset &&
export GIT_COMMITTER_EMAIL GIT_COMMITTER_NAME
export EDITOR VISUAL
+# Protect ourselves from common misconfiguration to export
+# CDPATH into the environment
+unset CDPATH
+
case $(echo $GIT_TRACE |tr "[A-Z]" "[a-z]") in
1|2|true)
echo "* warning: Some tests will not work if GIT_TRACE" \