Path to a log file where the CVS server interface well... logs
various stuff. See linkgit:git-cvsserver[1].
-gitcvs.usecrlfattr
+gitcvs.usecrlfattr::
If true, the server will look up the `crlf` attribute for
files to determine the '-k' modes to use. If `crlf` is set,
the '-k' mode will be left blank, so cvs clients will
lines.
--dirstat[=limit]::
- Output only the sub-directories that are impacted by a diff,
- and to what degree they are impacted. You can override the
- default cut-off in percent (3) by "--dirstat=limit". If you
- want to enable "cumulative" directory statistics, you can use
- the "--cumulative" flag, which adds up percentages recursively
- even when they have been already reported for a sub-directory.
+ Output the distribution of relative amount of changes (number of lines added or
+ removed) for each sub-directory. Directories with changes below
+ a cut-off percent (3% by default) are not shown. The cut-off percent
+ can be set with "--dirstat=limit". Changes in a child directory is not
+ counted for the parent directory, unless "--cumulative" is used.
--summary::
Output a condensed summary of extended header information
You don't exist. Go away!::
The passwd(5) gecos field couldn't be read
Your parents must have hated you!::
- The password(5) gecos field is longer than a giant static buffer.
+ The passwd(5) gecos field is longer than a giant static buffer.
Your sysadmin must hate you!::
- The password(5) name field is longer than a giant static buffer.
+ The passwd(5) name field is longer than a giant static buffer.
Discussion
----------
Iterate over all refs that match `<pattern>` and show them
according to the given `<format>`, after sorting them according
-to the given set of `<key>`. If `<max>` is given, stop after
+to the given set of `<key>`. If `<count>` is given, stop after
showing that many refs. The interpolated values in `<format>`
can optionally be quoted as string literals in the specified
host language allowing their direct evaluation in that language.
------------
% git name-rev 33db5f4d9027a10e477ccf054b2c1ab94f74c85a
-33db5f4d9027a10e477ccf054b2c1ab94f74c85a tags/v0.99^0~940
+33db5f4d9027a10e477ccf054b2c1ab94f74c85a tags/v0.99~940
------------
Now you are wiser, because you know that it happened 940 revisions before v0.99.
This is useful if your default address is not the address that is
subscribed to a list. If you use the sendmail binary, you must have
suitable privileges for the -f parameter.
+ Default is the value of the 'sendemail.envelopesender' configuration
+ variable; if that is unspecified, choosing the envelope sender is left
+ to your MTA.
--to::
Specify the primary recipient of the emails generated.
+
----------------------------------------------------------------
$ git pull
-...
+ ...
file foobar not up to date, cannot merge.
$ git stash
$ git pull
return to your original branch to make the emergency fix, like this:
+
----------------------------------------------------------------
-... hack hack hack ...
+# ... hack hack hack ...
$ git checkout -b my_wip
$ git commit -a -m "WIP"
$ git checkout master
$ git commit -a -m "Fix in a hurry"
$ git checkout my_wip
$ git reset --soft HEAD^
-... continue hacking ...
+# ... continue hacking ...
----------------------------------------------------------------
+
You can use 'git-stash' to simplify the above, like this:
+
----------------------------------------------------------------
-... hack hack hack ...
+# ... hack hack hack ...
$ git stash
$ edit emergency fix
$ git commit -a -m "Fix in a hurry"
$ git stash apply
-... continue hacking ...
+# ... continue hacking ...
----------------------------------------------------------------
Testing partial commits::
each change before committing:
+
----------------------------------------------------------------
-... hack hack hack ...
+# ... hack hack hack ...
$ git add --patch foo # add just first part to the index
$ git stash save --keep-index # save all other changes to the stash
$ edit/build/test first part
-$ git commit foo -m 'First part' # commit fully tested change
+$ git commit -m 'First part' # commit fully tested change
$ git stash pop # prepare to work on all other changes
-... repeat above five steps until one commit remains ...
+# ... repeat above five steps until one commit remains ...
$ edit/build/test remaining parts
$ git commit foo -m 'Remaining parts'
----------------------------------------------------------------
Cause the logical variables to be listed. In addition, all the
variables of the git configuration file .git/config are listed
as well. (However, the configuration variables listing functionality
- is deprecated in favor of 'git-config -l'.)
+ is deprecated in favor of 'git config -l'.)
EXAMPLE
--------
You don't exist. Go away!::
The passwd(5) gecos field couldn't be read
Your parents must have hated you!::
- The password(5) gecos field is longer than a giant static buffer.
+ The passwd(5) gecos field is longer than a giant static buffer.
Your sysadmin must hate you!::
- The password(5) name field is longer than a giant static buffer.
+ The passwd(5) name field is longer than a giant static buffer.
SEE ALSO
--------
SYNOPSIS
--------
-$GIT_DIR/info/attributes, gitattributes
+$GIT_DIR/info/attributes, .gitattributes
DESCRIPTION
Unset::
- Unsetting the `crlf` attribute on a path is meant to
- mark the path as a "binary" file. The path never goes
- through line endings conversion upon checkin/checkout.
+ Unsetting the `crlf` attribute on a path tells git not to
+ attempt any end-of-line conversion upon checkin or checkout.
Unspecified::
commit hash.
+USING ATTRIBUTE MACROS
+----------------------
+
+You do not want any end-of-line conversions applied to, nor textual diffs
+produced for, any binary file you track. You would need to specify e.g.
+
+------------
+*.jpg -crlf -diff
+------------
+
+but that may become cumbersome, when you have many attributes. Using
+attribute macros, you can specify groups of attributes set or unset at
+the same time. The system knows a built-in attribute macro, `binary`:
+
+------------
+*.jpg binary
+------------
+
+which is equivalent to the above. Note that the attribute macros can only
+be "Set" (see the above example that sets "binary" macro as if it were an
+ordinary attribute --- setting it in turn unsets "crlf" and "diff").
+
+
+DEFINING ATTRIBUTE MACROS
+-------------------------
+
+Custom attribute macros can be defined only in the `.gitattributes` file
+at the toplevel (i.e. not in any subdirectory). The built-in attribute
+macro "binary" is equivalent to:
+
+------------
+[attr]binary -diff -crlf
+------------
+
+
EXAMPLE
-------
SYNOPSIS
--------
-gitmodules
+$GIT_WORK_DIR/.gitmodules
DESCRIPTION
does not forbid it. However, there are a few things to keep in
mind.
-. 'git-commit-tree' (hence, 'git-commit' which uses it) issues
+. 'git-commit' and 'git-commit-tree' issues
a warning if the commit log message given to it does not look
like a valid UTF-8 string, unless you explicitly say your
project uses a legacy encoding. The way to say this is to
export PERL_PATH
LIB_FILE=libgit.a
-COMPAT_LIB = compat/lib.a
XDIFF_LIB=xdiff/lib.a
LIB_H += archive.h
LIB_H += ll-merge.h
LIB_H += log-tree.h
LIB_H += mailmap.h
+LIB_H += merge-recursive.h
LIB_H += object.h
LIB_H += pack.h
LIB_H += pack-refs.h
'-DGIT_INFO_PATH="$(infodir_SQ)"' $<
$(BUILT_INS): git$X
- $(QUIET_BUILT_IN)$(RM) $@ && ln git$X $@
+ $(QUIET_BUILT_IN)$(RM) $@ && \
+ ln git$X $@ 2>/dev/null || \
+ ln -s git$X $@ 2>/dev/null || \
+ cp git$X $@
common-cmds.h: ./generate-cmdlist.sh command-list.txt
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
$(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT)
-$(COMPAT_LIB): $(COMPAT_OBJS)
- $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(COMPAT_OBJS)
-
-git-shell$X: abspath.o ctype.o exec_cmd.o quote.o strbuf.o usage.o wrapper.o shell.o $(COMPAT_LIB)
- $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(COMPAT_LIB)
-
$(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H)
$(patsubst git-%$X,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h)
builtin-revert.o wt-status.o: wt-status.h
endif
bindir=$$(cd '$(DESTDIR_SQ)$(bindir_SQ)' && pwd) && \
execdir=$$(cd '$(DESTDIR_SQ)$(gitexec_instdir_SQ)' && pwd) && \
- if test "z$$bindir" != "z$$execdir"; \
- then \
- ln -f "$$bindir/git$X" "$$execdir/git$X" || \
- cp "$$bindir/git$X" "$$execdir/git$X"; \
- fi && \
- { $(foreach p,$(BUILT_INS), $(RM) "$$execdir/$p" && ln "$$execdir/git$X" "$$execdir/$p" ;) } && \
- if test "z$$bindir" != "z$$execdir"; \
- then \
- $(RM) "$$execdir/git$X"; \
- fi && \
+ { $(RM) "$$execdir/git-add$X" && \
+ ln git-add$X "$$execdir/git-add$X" 2>/dev/null || \
+ cp git-add$X "$$execdir/git-add$X"; } && \
+ { $(foreach p,$(filter-out git-add$X,$(BUILT_INS)), $(RM) "$$execdir/$p" && \
+ ln "$$execdir/git-add$X" "$$execdir/$p" 2>/dev/null || \
+ ln -s "git-add$X" "$$execdir/$p" 2>/dev/null || \
+ cp "$$execdir/git-add$X" "$$execdir/$p" || exit;) } && \
./check_bindir "z$$bindir" "z$$execdir" "$$bindir/git-add$X"
install-doc:
clean:
$(RM) *.o mozilla-sha1/*.o arm/*.o ppc/*.o compat/*.o xdiff/*.o \
- $(LIB_FILE) $(XDIFF_LIB) $(COMPAT_LIB)
+ $(LIB_FILE) $(XDIFF_LIB)
$(RM) $(ALL_PROGRAMS) $(BUILT_INS) git$X
$(RM) $(TEST_PROGRAMS)
$(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo common-cmds.h TAGS tags cscope*
/*
* A hunk to change lines at the beginning would begin with
* @@ -1,L +N,M @@
+ * but we need to be careful. -U0 that inserts before the second
+ * line also has this pattern.
*
* And a hunk to add to an empty file would begin with
* @@ -0,0 +N,M @@
* In other words, a hunk that is (frag->oldpos <= 1) with or
* without leading context must match at the beginning.
*/
- match_beginning = frag->oldpos <= 1;
+ match_beginning = (!frag->oldpos ||
+ (frag->oldpos == 1 && !unidiff_zero));
/*
* A hunk without trailing lines must match at the end.
}
/*
- * If the new thing isn't a branch and isn't HEAD and we're
- * not starting a new branch, and we want messages, and we
- * weren't on a branch, and we're moving to a new commit,
- * describe the old commit.
+ * If we were on a detached HEAD, but we are now moving to
+ * a new commit, we want to mention the old commit once more
+ * to remind the user that it might be lost.
*/
- if (!new->path && strcmp(new->name, "HEAD") && !opts->new_branch &&
- !opts->quiet && !old.path && new->commit != old.commit)
+ if (!opts->quiet && !old.path && new->commit != old.commit)
describe_detached_head("Previous HEAD position was", old.commit);
if (!old.commit) {
return !stat(path, &buf) && S_ISDIR(buf.st_mode);
}
+static void strip_trailing_slashes(char *dir)
+{
+ char *end = dir + strlen(dir);
+
+ while (dir < end - 1 && is_dir_sep(end[-1]))
+ end--;
+ *end = '\0';
+}
+
static void setup_reference(const char *repo)
{
const char *ref_git;
path = get_repo_path(repo_name, &is_bundle);
if (path)
- repo = path;
+ repo = xstrdup(make_nonrelative_path(repo_name));
else if (!strchr(repo_name, ':'))
repo = xstrdup(make_absolute_path(repo_name));
else
dir = xstrdup(argv[1]);
else
dir = guess_dir_name(repo_name, is_bundle, option_bare);
+ strip_trailing_slashes(dir);
if (!stat(dir, &buf))
die("destination directory '%s' already exists.", dir);
if (!option_bare) {
junk_work_tree = work_tree;
if (safe_create_leading_directories_const(work_tree) < 0)
- die("could not create leading directories of '%s'",
- work_tree);
+ die("could not create leading directories of '%s': %s",
+ work_tree, strerror(errno));
if (mkdir(work_tree, 0755))
- die("could not create work tree dir '%s'.", work_tree);
+ die("could not create work tree dir '%s': %s.",
+ work_tree, strerror(errno));
set_git_work_tree(work_tree);
}
junk_git_dir = git_dir;
}
entry->type = sha1_object_info(entry->idx.sha1, &entry->size);
- if (entry->type < 0)
- die("unable to get type of object %s",
- sha1_to_hex(entry->idx.sha1));
+ /*
+ * The error condition is checked in prepare_pack(). This is
+ * to permit a missing preferred base object to be ignored
+ * as a preferred base. Doing so can result in a larger
+ * pack file, but the transfer will still take place.
+ */
}
static int pack_offset_sort(const void *_a, const void *_b)
if (entry->no_try_delta)
continue;
- if (!entry->preferred_base)
+ if (!entry->preferred_base) {
nr_deltas++;
+ if (entry->type < 0)
+ die("unable to get type of object %s",
+ sha1_to_hex(entry->idx.sha1));
+ }
delta_list[n++] = entry;
}
#include "builtin.h"
#include "cache.h"
#include "pack.h"
-
+#include "pack-revindex.h"
#define MAX_CHAIN 50
else {
if (verify_one_pack(argv[1], verbose))
err = 1;
+ discard_revindex();
nothing_done = 0;
}
argc--; argv++;
} while (lo < hi);
die("internal error: pack revindex corrupt");
}
+
+void discard_revindex(void)
+{
+ if (pack_revindex_hashsz) {
+ int i;
+ for (i = 0; i < pack_revindex_hashsz; i++)
+ if (pack_revindex[i].revindex)
+ free(pack_revindex[i].revindex);
+ free(pack_revindex);
+ pack_revindex_hashsz = 0;
+ }
+}
};
struct revindex_entry *find_pack_revindex(struct packed_git *p, off_t ofs);
+void discard_revindex(void);
#endif
void reprepare_packed_git(void)
{
+ discard_revindex();
prepare_packed_git_run_once = 0;
prepare_packed_git();
}
#include "exec_cmd.h"
#include "strbuf.h"
-/* Stubs for functions that make no sense for git-shell. These stubs
- * are provided here to avoid linking in external redundant modules.
- */
-void release_pack_memory(size_t need, int fd){}
-void trace_argv_printf(const char **argv, const char *fmt, ...){}
-void trace_printf(const char *fmt, ...){}
-
-
static int do_generic_cmd(const char *me, char *arg)
{
const char *my_argv[4];
unsigned sf;
char buf[LARGE_PACKET_MAX + 2*FIX_SIZE];
char *suffix, *term;
+ int skip_pf = 0;
memcpy(buf, PREFIX, pf);
term = getenv("TERM");
return SIDEBAND_REMOTE_ERROR;
case 2:
buf[pf] = ' ';
- len += pf+1;
- while (1) {
- int brk = pf+1;
+ do {
+ char *b = buf;
+ int brk = 0;
- /* Break the buffer into separate lines. */
- while (brk < len) {
+ /*
+ * If the last buffer didn't end with a line
+ * break then we should not print a prefix
+ * this time around.
+ */
+ if (skip_pf) {
+ b += pf+1;
+ } else {
+ len += pf+1;
+ brk += pf+1;
+ }
+
+ /* Look for a line break. */
+ for (;;) {
brk++;
- if (buf[brk-1] == '\n' ||
- buf[brk-1] == '\r')
+ if (brk > len) {
+ brk = 0;
+ break;
+ }
+ if (b[brk-1] == '\n' ||
+ b[brk-1] == '\r')
break;
}
/*
* Let's insert a suffix to clear the end
- * of the screen line, but only if current
- * line data actually contains something.
+ * of the screen line if a line break was
+ * found. Also, if we don't skip the
+ * prefix, then a non-empty string must be
+ * present too.
*/
- if (brk > pf+1 + 1) {
+ if (brk > (skip_pf ? 0 : (pf+1 + 1))) {
char save[FIX_SIZE];
- memcpy(save, buf + brk, sf);
- buf[brk + sf - 1] = buf[brk - 1];
- memcpy(buf + brk - 1, suffix, sf);
- safe_write(err, buf, brk + sf);
- memcpy(buf + brk, save, sf);
- } else
- safe_write(err, buf, brk);
+ memcpy(save, b + brk, sf);
+ b[brk + sf - 1] = b[brk - 1];
+ memcpy(b + brk - 1, suffix, sf);
+ safe_write(err, b, brk + sf);
+ memcpy(b + brk, save, sf);
+ len -= brk;
+ } else {
+ int l = brk ? brk : len;
+ safe_write(err, b, l);
+ len -= l;
+ }
- if (brk < len) {
- memmove(buf + pf+1, buf + brk, len - brk);
- len = len - brk + pf+1;
- } else
- break;
- }
+ skip_pf = !brk;
+ memmove(buf + pf+1, b + brk, len);
+ } while (len);
continue;
case 1:
safe_write(out, buf + pf+1, len);
git diff victim >add-a-patch.with &&
git diff --unified=0 >add-a-patch.without &&
+ : insert at line two
+ for i in b a '"$L"' y
+ do
+ echo $i
+ done >victim &&
+ cat victim >insert-a-expect &&
+ git diff victim >insert-a-patch.with &&
+ git diff --unified=0 >insert-a-patch.without &&
+
: modify at the head
for i in a '"$L"' y
do
git diff --unified=0 >add-z-patch.without &&
: modify at the tail
- for i in a '"$L"' y
+ for i in b '"$L"' z
do
echo $i
done >victim &&
with) u= ;;
without) u='--unidiff-zero ' ;;
esac
- for kind in add-a add-z mod-a mod-z del-a del-z
+ for kind in add-a add-z insert-a mod-a mod-z del-a del-z
do
test_expect_success "apply $kind-patch $with context" '
cat original >victim &&
done
done
-for kind in add-a add-z mod-a mod-z del-a del-z
+for kind in add-a add-z insert-a mod-a mod-z del-a del-z
do
rm -f $kind-ng.without
sed -e "s/^diff --git /diff /" \
test-2-${packname_2}.idx \
test-3-${packname_3}.idx'
+test_expect_success \
+ 'verify pack -v' \
+ 'git verify-pack -v test-1-${packname_1}.idx \
+ test-2-${packname_2}.idx \
+ test-3-${packname_3}.idx'
+
test_expect_success \
'verify-pack catches mismatched .idx and .pack files' \
'cat test-1-${packname_1}.idx >test-3.idx &&
--- /dev/null
+#!/bin/sh
+#
+# Copyright (c) 2008 Google Inc.
+#
+
+test_description='git-pack-object with missing base
+
+'
+. ./test-lib.sh
+
+# Create A-B chain
+#
+test_expect_success \
+ 'setup base' \
+ 'for a in a b c d e f g h i; do echo $a >>text; done &&
+ echo side >side &&
+ git update-index --add text side &&
+ A=$(echo A | git commit-tree $(git write-tree)) &&
+
+ echo m >>text &&
+ git update-index text &&
+ B=$(echo B | git commit-tree $(git write-tree) -p $A) &&
+ git update-ref HEAD $B
+ '
+
+# Create repository with C whose parent is B.
+# Repository contains C, C^{tree}, C:text, B, B^{tree}.
+# Repository is missing B:text (best delta base for C:text).
+# Repository is missing A (parent of B).
+# Repository is missing A:side.
+#
+test_expect_success \
+ 'setup patch_clone' \
+ 'base_objects=$(pwd)/.git/objects &&
+ (mkdir patch_clone &&
+ cd patch_clone &&
+ git init &&
+ echo "$base_objects" >.git/objects/info/alternates &&
+ echo q >>text &&
+ git read-tree $B &&
+ git update-index text &&
+ git update-ref HEAD $(echo C | git commit-tree $(git write-tree) -p $B) &&
+ rm .git/objects/info/alternates &&
+
+ git --git-dir=../.git cat-file commit $B |
+ git hash-object -t commit -w --stdin &&
+
+ git --git-dir=../.git cat-file tree "$B^{tree}" |
+ git hash-object -t tree -w --stdin
+ ) &&
+ C=$(git --git-dir=patch_clone/.git rev-parse HEAD)
+ '
+
+# Clone patch_clone indirectly by cloning base and fetching.
+#
+test_expect_success \
+ 'indirectly clone patch_clone' \
+ '(mkdir user_clone &&
+ cd user_clone &&
+ git init &&
+ git pull ../.git &&
+ test $(git rev-parse HEAD) = $B &&
+
+ git pull ../patch_clone/.git &&
+ test $(git rev-parse HEAD) = $C
+ )
+ '
+
+# Cloning the patch_clone directly should fail.
+#
+test_expect_success \
+ 'clone of patch_clone is incomplete' \
+ '(mkdir user_direct &&
+ cd user_direct &&
+ git init &&
+ test_must_fail git fetch ../patch_clone/.git
+ )
+ '
+
+test_done
cat > test/expect << EOF
* remote origin
- URL: $(pwd)/one/.git
+ URL: $(pwd)/one
Remote branch merged with 'git pull' while on branch master
master
New remote branch (next fetch will store in remotes/origin)
cat > test/expect << EOF
* remote origin
- URL: $(pwd)/one/.git
+ URL: $(pwd)/one
Remote branch merged with 'git pull' while on branch master
master
Tracked remote branches
cat > test/expect << EOF
Pruning origin
-URL: $(pwd)/one/.git
+URL: $(pwd)/one
* [would prune] origin/side2
EOF
'
+test_expect_success 'clone to destination with trailing /' '
+
+ git clone src target-1/ &&
+ T=$( cd target-1 && git rev-parse HEAD ) &&
+ S=$( cd src && git rev-parse HEAD ) &&
+ test "$T" = "$S"
+
+'
+
+test_expect_success 'clone to destination with extra trailing /' '
+
+ git clone src target-2/// &&
+ T=$( cd target-2 && git rev-parse HEAD ) &&
+ S=$( cd src && git rev-parse HEAD ) &&
+ test "$T" = "$S"
+
+'
+
test_done