LF at the end of lines. Currently, which paths to consider
'text' (i.e. be subjected to the autocrlf mechanism) is
decided purely based on the contents, but the plan is to
- allow users to explicitly override this heuristics based on
+ allow users to explicitly override this heuristic based on
paths.
- The behaviour of 'git-apply', when run in a subdirectory,
while (my ($text, $included) = each %include) {
if (! exists $included{$text} &&
(my $base = $text) =~ s/\.txt$//) {
- my ($suffix) = '1';
- if ($base eq 'git') {
- $suffix = '7'; # yuck...
- }
- print "$base.html $base.$suffix : ", join(" ", keys %$included), "\n";
+ print "$base.html $base.xml : ", join(" ", keys %$included), "\n";
}
}
Additional email headers to include in a patch to be submitted
by mail. See gitlink:git-format-patch[1].
+format.suffix::
+ The default for format-patch is to output files with the suffix
+ `.patch`. Use this variable to change that suffix (make sure to
+ include the dot if you want it).
+
gc.packrefs::
`git gc` does not run `git pack-refs` in a bare repository by
default so that older dumb-transport clients can still fetch
-f::
Allow adding otherwise ignored files.
-\i, \--interactive::
+-i, \--interactive::
Add modified contents in the working tree interactively to
the index.
SYNOPSIS
--------
[verse]
-'git-branch' [--color | --no-color] [-r | -a] [-v [--abbrev=<length>]]
+'git-branch' [--color | --no-color] [-r | -a]
+ [-v [--abbrev=<length> | --no-abbrev]]
'git-branch' [-l] [-f] <branchname> [<start-point>]
'git-branch' (-m | -M) [<oldbranch>] <newbranch>
'git-branch' (-d | -D) [-r] <branchname>...
Alter minimum display length for sha1 in output listing,
default value is 7.
+--no-abbrev::
+ Display the full sha1s in output listing rather than abbreviating them.
+
<branchname>::
The name of the branch to create or delete.
The new branch name must pass all checks defined by
Some workflows require that one or more branches of development on one
machine be replicated on another machine, but the two machines cannot
be directly connected so the interactive git protocols (git, ssh,
-rsync, http) cannot be used. This command provides suport for
+rsync, http) cannot be used. This command provides support for
git-fetch and git-pull to operate by packaging objects and references
in an archive at the originating machine, then importing those into
another repository using gitlink:git-fetch[1] and gitlink:git-pull[1]
gitlink:git-fetch[1].
[git-rev-list-args...]::
- A list of arguments, accepatble to git-rev-parse and
+ A list of arguments, acceptable to git-rev-parse and
git-rev-list, that specify the specific objects and references
to transport. For example, "master~10..master" causes the
current master reference to be packaged along with all objects
[refname...]::
A list of references used to limit the references reported as
available. This is principally of use to git-fetch, which
- expects to recieve only those references asked for and not
+ expects to receive only those references asked for and not
necessarily everything in the pack (in this case, git-bundle is
acting like gitlink:git-fetch-pack[1]).
master~10..master, master --since=10.days.ago).
It is very important that the basis used be held by the destination.
-It is ok to err on the side of conservatism, causing the bundle file
+It is okay to err on the side of conservatism, causing the bundle file
to contain objects already in the destination as these are ignored
when unpacking at the destination.
--patches <dir>::
The directory to find the quilt patches and the
quilt series file.
-
- The default for the patch directory is patches
- or the value of the $QUILT_PATCHES environment
- variable.
++
+The default for the patch directory is patches
+or the value of the $QUILT_PATCHES environment
+variable.
Author
------
--bcc::
Specify a "Bcc:" value for each email.
-
- The --bcc option must be repeated for each user you want on the bcc list.
++
+The --bcc option must be repeated for each user you want on the bcc list.
--cc::
Specify a starting "Cc:" value for each email.
-
- The --cc option must be repeated for each user you want on the cc list.
++
+The --cc option must be repeated for each user you want on the cc list.
--chain-reply-to, --no-chain-reply-to::
If this is set, each email will be sent as a reply to the previous
Specify the primary recipient of the emails generated.
Generally, this will be the upstream maintainer of the
project involved.
-
- The --to option must be repeated for each user you want on the to list.
++
+The --to option must be repeated for each user you want on the to list.
Author
transports (eg svn+ssh://), you must include the username in
the URL, eg svn+ssh://foo@svn.bar.com/project
---prefix=<prefix>
+--prefix=<prefix>::
This allows one to specify a prefix which is prepended
to the names of remotes if trunk/branches/tags are
specified. The prefix does not automatically include a
This fetches revisions from the SVN parent of the current HEAD
and rebases the current (uncommitted to SVN) work against it.
- This works similarly to 'svn update' or 'git-pull' except that
- it preserves linear history with 'git-rebase' instead of
- 'git-merge' for ease of dcommit-ing with git-svn.
+This works similarly to 'svn update' or 'git-pull' except that
+it preserves linear history with 'git-rebase' instead of
+'git-merge' for ease of dcommit-ing with git-svn.
- This accepts all options that 'git-svn fetch' and 'git-rebase'
- accepts. However '--fetch-all' only fetches from the current
- [svn-remote], and not all [svn-remote] definitions.
+This accepts all options that 'git-svn fetch' and 'git-rebase'
+accepts. However '--fetch-all' only fetches from the current
+[svn-remote], and not all [svn-remote] definitions.
- Like 'git-rebase'; this requires that the working tree be clean
- and have no uncommitted changes.
+Like 'git-rebase'; this requires that the working tree be clean
+and have no uncommitted changes.
'dcommit'::
Commit each diff from a specified head directly to the SVN
alternative to HEAD.
This is advantageous over 'set-tree' (below) because it produces
cleaner, more linear history.
+--
'log'::
This should make it easy to look up svn log messages when svn
users refer to -r/--revision numbers.
++
+The following features from `svn log' are supported:
++
+--
+--revision=<n>[:<n>];;
+ is supported, non-numeric args are not:
+ HEAD, NEXT, BASE, PREV, etc ...
+-v/--verbose;;
+ it's not completely compatible with the --verbose
+ output in svn log, but reasonably close.
+--limit=<n>;;
+ is NOT the same as --max-count, doesn't count
+ merged/excluded commits
+--incremental;;
+ supported
+--
++
+New features:
++
+--
+--show-commit;;
+ shows the git commit sha1, as well
+--oneline;;
+ our version of --pretty=oneline
+--
++
+Any other arguments are passed directly to `git log'
- The following features from `svn log' are supported:
-
- --revision=<n>[:<n>] - is supported, non-numeric args are not:
- HEAD, NEXT, BASE, PREV, etc ...
- -v/--verbose - it's not completely compatible with
- the --verbose output in svn log, but
- reasonably close.
- --limit=<n> - is NOT the same as --max-count,
- doesn't count merged/excluded commits
- --incremental - supported
-
- New features:
-
- --show-commit - shows the git commit sha1, as well
- --oneline - our version of --pretty=oneline
-
- Any other arguments are passed directly to `git log'
-
+--
'set-tree'::
You should consider using 'dcommit' instead of this command.
Commit specified commit or tree objects to SVN. This relies on
Make git-svn less verbose.
--repack[=<n>]::
---repack-flags=<flags>
- These should help keep disk usage sane for large fetches
- with many revisions.
+--repack-flags=<flags>::
+
+These should help keep disk usage sane for large fetches
+with many revisions.
- --repack takes an optional argument for the number of revisions
- to fetch before repacking. This defaults to repacking every
- 1000 commits fetched if no argument is specified.
+--repack takes an optional argument for the number of revisions
+to fetch before repacking. This defaults to repacking every
+1000 commits fetched if no argument is specified.
- --repack-flags are passed directly to gitlink:git-repack[1].
+--repack-flags are passed directly to gitlink:git-repack[1].
+[verse]
config key: svn.repack
config key: svn.repackflags
svn.noMetadata::
svn-remote.<name>.noMetadata::
- This gets rid of the git-svn-id: lines at the end of every commit.
- If you lose your .git/svn/git-svn/.rev_db file, git-svn will not
- be able to rebuild it and you won't be able to fetch again,
- either. This is fine for one-shot imports.
+This gets rid of the git-svn-id: lines at the end of every commit.
+
+If you lose your .git/svn/git-svn/.rev_db file, git-svn will not
+be able to rebuild it and you won't be able to fetch again,
+either. This is fine for one-shot imports.
- The 'git-svn log' command will not work on repositories using
- this, either. Using this conflicts with the 'useSvmProps'
- option for (hopefully) obvious reasons.
+The 'git-svn log' command will not work on repositories using
+this, either. Using this conflicts with the 'useSvmProps'
+option for (hopefully) obvious reasons.
svn.useSvmProps::
svn-remote.<name>.useSvmProps::
- This allows git-svn to re-map repository URLs and UUIDs from
- mirrors created using SVN::Mirror (or svk) for metadata.
- If an SVN revision has a property, "svm:headrev", it is likely
- that the revision was created by SVN::Mirror (also used by SVK).
- The property contains a repository UUID and a revision. We want
- to make it look like we are mirroring the original URL, so
- introduce a helper function that returns the original identity
- URL and UUID, and use it when generating metadata in commit
- messages.
+This allows git-svn to re-map repository URLs and UUIDs from
+mirrors created using SVN::Mirror (or svk) for metadata.
+
+If an SVN revision has a property, "svm:headrev", it is likely
+that the revision was created by SVN::Mirror (also used by SVK).
+The property contains a repository UUID and a revision. We want
+to make it look like we are mirroring the original URL, so
+introduce a helper function that returns the original identity
+URL and UUID, and use it when generating metadata in commit
+messages.
svn.useSvnsyncProps::
svn-remote.<name>.useSvnsyncprops::
--
-Basic Examples
-~~~~~~~~~~~~~~
+BASIC EXAMPLES
+--------------
Tracking and contributing to a the trunk of a Subversion-managed project:
# with the appropriate name):
git reset --hard remotes/trunk
# You may only dcommit to one branch/tag/trunk at a time. The usage
-# of dcommit/rebase/show-ignore should be teh same as above.
+# of dcommit/rebase/show-ignore should be the same as above.
------------------------------------------------------------------------
REBASE VS. PULL/MERGE
true parent commits, without taking grafts nor history
simplification into account.
+ * 'format:'
++
+The 'format:' format allows you to specify which information
+you want to show. It works a little bit like printf format,
+with the notable exception that you get a newline with '%n'
+instead of '\n'.
+
+E.g, 'format:"The author of %h was %an, %ar%nThe title was >>%s<<"'
+would show something like this:
+
+The author of fe6e0ee was Junio C Hamano, 23 hours ago
+The title was >>t4119: test autocomputing -p<n> for traditional diff input.<<
+
+The placeholders are:
+
+- '%H': commit hash
+- '%h': abbreviated commit hash
+- '%T': tree hash
+- '%t': abbreviated tree hash
+- '%P': parent hashes
+- '%p': abbreviated parent hashes
+- '%an': author name
+- '%ae': author email
+- '%ad': author date
+- '%aD': author date, RFC2822 style
+- '%ar': author date, relative
+- '%at': author date, UNIX timestamp
+- '%cn': committer name
+- '%ce': committer email
+- '%cd': committer date
+- '%cD': committer date, RFC2822 style
+- '%cr': committer date, relative
+- '%ct': committer date, UNIX timestamp
+- '%e': encoding
+- '%s': subject
+- '%b': body
+- '%Cred': switch color to red
+- '%Cgreen': switch color to green
+- '%Cblue': switch color to blue
+- '%Creset': reset color
+- '%n': newline
+
+
--encoding[=<encoding>]::
The commit objects record the encoding used for the log message
in their encoding header; this option can be used to tell the
command to re-code the commit log message in the encoding
preferred by the user. For non plumbing commands this
defaults to UTF-8.
+
#
# Define NO_ICONV if your libc does not properly support iconv.
#
+# Define OLD_ICONV if your library has an old iconv(), where the second
+# (input buffer pointer) parameter is declared with type (const char **).
+#
# Define NO_R_TO_GCC if your gcc does not like "-R/path/lib" that
# tells runtime paths to dynamic libraries; "-Wl,-rpath=/path/lib"
# is used instead.
NO_STRCASESTR = YesPlease
NO_SYMLINK_HEAD = YesPlease
NEEDS_LIBICONV = YesPlease
- NO_C99_FORMAT = YesPlease
NO_FAST_WORKING_DIRECTORY = UnfortunatelyYes
NO_TRUSTABLE_FILEMODE = UnfortunatelyYes
# There are conflicting reports about this.
BASIC_CFLAGS += -DNO_ICONV
endif
+ifdef OLD_ICONV
+ BASIC_CFLAGS += -DOLD_ICONV
+endif
+
ifdef PPC_SHA1
SHA1_HEADER = "ppc/sha1.h"
LIB_OBJS += ppc/sha1.o ppc/sha1ppc.o
$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
$(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT)
-$(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H)
+$(LIB_OBJS) $(BUILTIN_OBJS) fetch.o: $(LIB_H)
$(patsubst git-%$X,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h)
$(DIFF_OBJS): diffcore.h
memset(&ar, 0, sizeof(ar));
tree_idx = parse_archive_args(argc, argv, &ar);
- if (prefix == NULL)
- prefix = setup_git_directory();
argv += tree_idx;
parse_treeish_arg(argv, &ar.args, prefix);
#include "builtin.h"
static const char builtin_branch_usage[] =
- "git-branch [-r] (-d | -D) <branchname> | [-l] [-f] <branchname> [<start-point>] | (-m | -M) [<oldbranch>] <newbranch> | [--color | --no-color] [-r | -a] [-v [--abbrev=<length>]]";
+ "git-branch [-r] (-d | -D) <branchname> | [-l] [-f] <branchname> [<start-point>] | (-m | -M) [<oldbranch>] <newbranch> | [--color | --no-color] [-r | -a] [-v [--abbrev=<length> | --no-abbrev]]";
#define REF_UNKNOWN_TYPE 0x00
#define REF_LOCAL_BRANCH 0x01
reflog = 1;
continue;
}
+ if (!prefixcmp(arg, "--no-abbrev")) {
+ abbrev = 0;
+ continue;
+ }
if (!prefixcmp(arg, "--abbrev=")) {
- abbrev = atoi(arg+9);
+ abbrev = strtoul(arg + 9, NULL, 10);
+ if (abbrev < MINIMUM_ABBREV)
+ abbrev = MINIMUM_ABBREV;
+ else if (abbrev > 40)
+ abbrev = 40;
continue;
}
if (!strcmp(arg, "-v")) {
unsigned long *size,
unsigned char *sha1_ret);
-const char *show_date(unsigned long time, int timezone, int relative);
+enum date_mode { DATE_NORMAL = 0, DATE_RELATIVE, DATE_SHORT };
+const char *show_date(unsigned long time, int timezone, enum date_mode mode);
const char *show_rfc2822_date(unsigned long time, int timezone);
int parse_date(const char *date, char *buf, int bufsize);
void datestamp(char *buf, int bufsize);
#include "commit.h"
#include "pkt-line.h"
#include "utf8.h"
+#include "interpolate.h"
int save_commit_buffer = 1;
{ "full", 5, CMIT_FMT_FULL },
{ "fuller", 5, CMIT_FMT_FULLER },
{ "oneline", 1, CMIT_FMT_ONELINE },
+ { "format:", 7, CMIT_FMT_USERFORMAT},
};
+static char *user_format;
+
enum cmit_fmt get_commit_format(const char *arg)
{
int i;
return CMIT_FMT_DEFAULT;
if (*arg == '=')
arg++;
+ if (!prefixcmp(arg, "format:")) {
+ if (user_format)
+ free(user_format);
+ user_format = xstrdup(arg + 7);
+ return CMIT_FMT_USERFORMAT;
+ }
for (i = 0; i < ARRAY_SIZE(cmt_fmts); i++) {
if (!strncmp(arg, cmt_fmts[i].n, cmt_fmts[i].cmp_len) &&
!strncmp(arg, cmt_fmts[i].n, strlen(arg)))
return out;
}
+static char *xstrndup(const char *text, int len)
+{
+ char *result = xmalloc(len + 1);
+ memcpy(result, text, len);
+ result[len] = '\0';
+ return result;
+}
+
+static void fill_person(struct interp *table, const char *msg, int len)
+{
+ int start, end, tz = 0;
+ unsigned long date;
+ char *ep;
+
+ /* parse name */
+ for (end = 0; end < len && msg[end] != '<'; end++)
+ ; /* do nothing */
+ start = end + 1;
+ while (end > 0 && isspace(msg[end - 1]))
+ end--;
+ table[0].value = xstrndup(msg, end);
+
+ if (start >= len)
+ return;
+
+ /* parse email */
+ for (end = start + 1; end < len && msg[end] != '>'; end++)
+ ; /* do nothing */
+
+ if (end >= len)
+ return;
+
+ table[1].value = xstrndup(msg + start, end - start);
+
+ /* parse date */
+ for (start = end + 1; start < len && isspace(msg[start]); start++)
+ ; /* do nothing */
+ if (start >= len)
+ return;
+ date = strtoul(msg + start, &ep, 10);
+ if (msg + start == ep)
+ return;
+
+ table[5].value = xstrndup(msg + start, ep - msg + start);
+
+ /* parse tz */
+ for (start = ep - msg + 1; start < len && isspace(msg[start]); start++)
+ ; /* do nothing */
+ if (start + 1 < len) {
+ tz = strtoul(msg + start + 1, NULL, 10);
+ if (msg[start] == '-')
+ tz = -tz;
+ }
+
+ interp_set_entry(table, 2, show_date(date, tz, 0));
+ interp_set_entry(table, 3, show_rfc2822_date(date, tz));
+ interp_set_entry(table, 4, show_date(date, tz, 1));
+}
+
+static long format_commit_message(const struct commit *commit,
+ const char *msg, char *buf, unsigned long space)
+{
+ struct interp table[] = {
+ { "%H" }, /* commit hash */
+ { "%h" }, /* abbreviated commit hash */
+ { "%T" }, /* tree hash */
+ { "%t" }, /* abbreviated tree hash */
+ { "%P" }, /* parent hashes */
+ { "%p" }, /* abbreviated parent hashes */
+ { "%an" }, /* author name */
+ { "%ae" }, /* author email */
+ { "%ad" }, /* author date */
+ { "%aD" }, /* author date, RFC2822 style */
+ { "%ar" }, /* author date, relative */
+ { "%at" }, /* author date, UNIX timestamp */
+ { "%cn" }, /* committer name */
+ { "%ce" }, /* committer email */
+ { "%cd" }, /* committer date */
+ { "%cD" }, /* committer date, RFC2822 style */
+ { "%cr" }, /* committer date, relative */
+ { "%ct" }, /* committer date, UNIX timestamp */
+ { "%e" }, /* encoding */
+ { "%s" }, /* subject */
+ { "%b" }, /* body */
+ { "%Cred" }, /* red */
+ { "%Cgreen" }, /* green */
+ { "%Cblue" }, /* blue */
+ { "%Creset" }, /* reset color */
+ { "%n" } /* newline */
+ };
+ enum interp_index {
+ IHASH = 0, IHASH_ABBREV,
+ ITREE, ITREE_ABBREV,
+ IPARENTS, IPARENTS_ABBREV,
+ IAUTHOR_NAME, IAUTHOR_EMAIL,
+ IAUTHOR_DATE, IAUTHOR_DATE_RFC2822, IAUTHOR_DATE_RELATIVE,
+ IAUTHOR_TIMESTAMP,
+ ICOMMITTER_NAME, ICOMMITTER_EMAIL,
+ ICOMMITTER_DATE, ICOMMITTER_DATE_RFC2822,
+ ICOMMITTER_DATE_RELATIVE, ICOMMITTER_TIMESTAMP,
+ IENCODING,
+ ISUBJECT,
+ IBODY,
+ IRED, IGREEN, IBLUE, IRESET_COLOR,
+ INEWLINE
+ };
+ struct commit_list *p;
+ char parents[1024];
+ int i;
+ enum { HEADER, SUBJECT, BODY } state;
+
+ if (INEWLINE + 1 != ARRAY_SIZE(table))
+ die("invalid interp table!");
+
+ /* these are independent of the commit */
+ interp_set_entry(table, IRED, "\033[31m");
+ interp_set_entry(table, IGREEN, "\033[32m");
+ interp_set_entry(table, IBLUE, "\033[34m");
+ interp_set_entry(table, IRESET_COLOR, "\033[m");
+ interp_set_entry(table, INEWLINE, "\n");
+
+ /* these depend on the commit */
+ if (!commit->object.parsed)
+ parse_object(commit->object.sha1);
+ interp_set_entry(table, IHASH, sha1_to_hex(commit->object.sha1));
+ interp_set_entry(table, IHASH_ABBREV,
+ find_unique_abbrev(commit->object.sha1,
+ DEFAULT_ABBREV));
+ interp_set_entry(table, ITREE, sha1_to_hex(commit->tree->object.sha1));
+ interp_set_entry(table, ITREE_ABBREV,
+ find_unique_abbrev(commit->tree->object.sha1,
+ DEFAULT_ABBREV));
+ for (i = 0, p = commit->parents;
+ p && i < sizeof(parents) - 1;
+ p = p->next)
+ i += snprintf(parents + i, sizeof(parents) - i - 1, "%s ",
+ sha1_to_hex(p->item->object.sha1));
+ interp_set_entry(table, IPARENTS, parents);
+ for (i = 0, p = commit->parents;
+ p && i < sizeof(parents) - 1;
+ p = p->next)
+ i += snprintf(parents + i, sizeof(parents) - i - 1, "%s ",
+ find_unique_abbrev(p->item->object.sha1,
+ DEFAULT_ABBREV));
+ interp_set_entry(table, IPARENTS_ABBREV, parents);
+
+ for (i = 0, state = HEADER; msg[i] && state < BODY; i++) {
+ int eol;
+ for (eol = i; msg[eol] && msg[eol] != '\n'; eol++)
+ ; /* do nothing */
+
+ if (state == SUBJECT) {
+ table[ISUBJECT].value = xstrndup(msg + i, eol - i);
+ i = eol;
+ }
+ if (i == eol) {
+ state++;
+ /* strip empty lines */
+ while (msg[eol + 1] == '\n')
+ eol++;
+ } else if (!prefixcmp(msg + i, "author "))
+ fill_person(table + IAUTHOR_NAME,
+ msg + i + 7, eol - i - 7);
+ else if (!prefixcmp(msg + i, "committer "))
+ fill_person(table + ICOMMITTER_NAME,
+ msg + i + 10, eol - i - 10);
+ else if (!prefixcmp(msg + i, "encoding "))
+ table[IENCODING].value = xstrndup(msg + i, eol - i);
+ i = eol;
+ }
+ if (msg[i])
+ table[IBODY].value = xstrdup(msg + i);
+ for (i = 0; i < ARRAY_SIZE(table); i++)
+ if (!table[i].value)
+ interp_set_entry(table, i, "<unknown>");
+
+ interpolate(buf, space, user_format, table, ARRAY_SIZE(table));
+ interp_clear_table(table, ARRAY_SIZE(table));
+
+ return strlen(buf);
+}
+
unsigned long pretty_print_commit(enum cmit_fmt fmt,
const struct commit *commit,
unsigned long len,
char *reencoded;
char *encoding;
+ if (fmt == CMIT_FMT_USERFORMAT)
+ return format_commit_message(commit, msg, buf, space);
+
encoding = (git_log_output_encoding
? git_log_output_encoding
: git_commit_encoding);
CMIT_FMT_FULLER,
CMIT_FMT_ONELINE,
CMIT_FMT_EMAIL,
+ CMIT_FMT_USERFORMAT,
CMIT_FMT_UNSPECIFIED,
};
return gmtime(&t);
}
-const char *show_date(unsigned long time, int tz, int relative)
+const char *show_date(unsigned long time, int tz, enum date_mode mode)
{
struct tm *tm;
static char timebuf[200];
- if (relative) {
+ if (mode == DATE_RELATIVE) {
unsigned long diff;
struct timeval now;
gettimeofday(&now, NULL);
tm = time_to_tm(time, tz);
if (!tm)
return NULL;
- sprintf(timebuf, "%.3s %.3s %d %02d:%02d:%02d %d %+05d",
- weekday_names[tm->tm_wday],
- month_names[tm->tm_mon],
- tm->tm_mday,
- tm->tm_hour, tm->tm_min, tm->tm_sec,
- tm->tm_year + 1900, tz);
+ if (mode == DATE_SHORT)
+ sprintf(timebuf, "%04d-%02d-%02d", tm->tm_year + 1900,
+ tm->tm_mon + 1, tm->tm_mday);
+ else
+ sprintf(timebuf, "%.3s %.3s %d %02d:%02d:%02d %d %+05d",
+ weekday_names[tm->tm_wday],
+ month_names[tm->tm_mon],
+ tm->tm_mday,
+ tm->tm_hour, tm->tm_min, tm->tm_sec,
+ tm->tm_year + 1900, tz);
return timebuf;
}
#include <netdb.h>
#include <pwd.h>
#include <inttypes.h>
+#if defined(__CYGWIN__)
+#undef _XOPEN_SOURCE
+#include <grp.h>
+#define _XOPEN_SOURCE 600
+#else
#undef _ALL_SOURCE /* AIX 5.3L defines a struct list with _ALL_SOURCE. */
#include <grp.h>
#define _ALL_SOURCE 1
+#endif
#ifndef NO_ICONV
#include <iconv.h>
#
# Cleanup unreachable files and optimize the repository.
-USAGE='git-gc [--prune]'
+USAGE='[--prune]'
SUBDIRECTORY_OK=Yes
. git-sh-setup
git-update-index --refresh 2>/dev/null
new_head=$(git-rev-parse --verify "$1^0") &&
git-read-tree -v -m -u --exclude-per-directory=.gitignore $head "$new_head" &&
- finish "$new_head" "Fast forward"
+ finish "$new_head" "Fast forward" || exit
dropsave
exit 0
;;
{ "add", cmd_add, RUN_SETUP | NOT_BARE },
{ "annotate", cmd_annotate, USE_PAGER },
{ "apply", cmd_apply },
- { "archive", cmd_archive },
+ { "archive", cmd_archive, RUN_SETUP },
{ "blame", cmd_blame, RUN_SETUP },
{ "branch", cmd_branch, RUN_SETUP },
{ "bundle", cmd_bundle },
struct xml_ctx *ctx = (struct xml_ctx *)userData;
free(ctx->cdata);
ctx->cdata = xmalloc(len + 1);
- strlcpy(ctx->cdata, s, len + 1);
+ /* NB: 's' is not null-terminated, can not use strlcpy here */
+ memcpy(ctx->cdata, s, len);
+ ctx->cdata[len] = '\0';
}
static struct remote_lock *lock_remote(const char *path, long timeout)
return;
path += 8;
obj_hex = xmalloc(strlen(path));
- strlcpy(obj_hex, path, 3);
+ /* NB: path is not null-terminated, can not use strlcpy here */
+ memcpy(obj_hex, path, 2);
strcpy(obj_hex + 2, path + 3);
one_remote_object(obj_hex);
free(obj_hex);
/* If it's a symref, set the refname; otherwise try for a sha1 */
if (!prefixcmp((char *)buffer.buffer, "ref: ")) {
*symref = xmalloc(buffer.posn - 5);
- strlcpy(*symref, (char *)buffer.buffer + 5, buffer.posn - 5);
+ memcpy(*symref, (char *)buffer.buffer + 5, buffer.posn - 6);
+ (*symref)[buffer.posn - 6] = '\0';
} else {
get_sha1_hex(buffer.buffer, sha1);
}
sha1, sha1);
opt->diffopt.stat_sep = buffer;
}
- } else {
+ } else if (opt->commit_format != CMIT_FMT_USERFORMAT) {
fputs(diff_get_color(opt->diffopt.color_diff, DIFF_COMMIT),
stdout);
if (opt->commit_format != CMIT_FMT_ONELINE)
return -1;
}
+#ifndef NO_SYMLINK_HEAD
done:
+#endif
if (logmsg && !read_ref(refs_heads_master, new_sha1))
log_ref_write(ref_target, old_sha1, new_sha1, logmsg);
# un-annotated tag
refname_type="tag"
short_refname=${refname##refs/tags/}
- if [ $allowunannotated != "true" ]; then
+ if [ "$allowunannotated" != "true" ]; then
echo "*** The un-annotated tag, $short_refname is not allowed in this repository" >&2
echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2
exit 1
# This shows all log entries that are not already covered by
# another ref - i.e. commits that are now accessible from this
# ref that were previously not accessible
- git-rev-parse --not --all | git-rev-list --stdin --pretty $newref
+ git log $newrev --not --all
echo $LOGEND
else
# oldrev is valid
baserev=$(git-merge-base $oldrev $newrev)
# Commit with a parent
- for rev in $(git-rev-parse --not --all | git-rev-list --stdin $newrev ^$baserev)
+ for rev in $(git-rev-list $newrev --not $baserev --all)
do
revtype=$(git-cat-file -t "$rev")
echo " via $rev ($revtype)"
fi
echo ""
echo $LOGBEGIN
- git-rev-parse --not --all |
- git-rev-list --stdin --pretty $newrev ^$baserev
+ git log $newrev --not $baserev --all
echo $LOGEND
echo ""
echo "Diffstat:"
- git-diff-tree --no-color --stat -M -C --find-copies-harder $newrev ^$baserev
+ git-diff-tree --no-color --stat -M -C --find-copies-harder $baserev..$newrev
fi
;;
"annotated tag")
/* This code is originally from http://www.cl.cam.ac.uk/~mgk25/ucs/ */
+typedef unsigned int ucs_char_t; /* assuming 32bit int */
+
struct interval {
int first;
int last;
};
/* auxiliary function for binary search in interval table */
-static int bisearch(wchar_t ucs, const struct interval *table, int max) {
+static int bisearch(ucs_char_t ucs, const struct interval *table, int max) {
int min = 0;
int mid;
* ISO 8859-1 and WGL4 characters, Unicode control characters,
* etc.) have a column width of 1.
*
- * This implementation assumes that wchar_t characters are encoded
+ * This implementation assumes that ucs_char_t characters are encoded
* in ISO 10646.
*/
-static int wcwidth(wchar_t ch)
+static int wcwidth(ucs_char_t ch)
{
/*
* Sorted list of non-overlapping intervals of non-spacing characters,
int utf8_width(const char **start)
{
unsigned char *s = (unsigned char *)*start;
- wchar_t ch;
+ ucs_char_t ch;
if (*s < 0x80) {
/* 0xxxxxxx */
/*
* Wrap the text, if necessary. The variable indent is the indent for the
* first line, indent2 is the indent for all other lines.
+ * If indent is negative, assume that already -indent columns have been
+ * consumed (and no extra indent is necessary for the first line).
*/
-void print_wrapped_text(const char *text, int indent, int indent2, int width)
+int print_wrapped_text(const char *text, int indent, int indent2, int width)
{
int w = indent, assume_utf8 = is_utf8(text);
const char *bol = text, *space = NULL;
+ if (indent < 0) {
+ w = -indent;
+ space = text;
+ }
+
for (;;) {
char c = *text;
if (!c || isspace(c)) {
else
print_spaces(indent);
fwrite(start, text - start, 1, stdout);
- if (!c) {
- putchar('\n');
- return;
- } else if (c == '\t')
+ if (!c)
+ return w;
+ else if (c == '\t')
w |= 0x07;
space = text;
w++;
}
else {
putchar('\n');
- text = bol = space + 1;
+ text = bol = space + isspace(*space);
space = NULL;
w = indent = indent2;
}
text++;
}
}
+ return w;
}
int is_encoding_utf8(const char *name)
* with iconv. If the conversion fails, returns NULL.
*/
#ifndef NO_ICONV
+#ifdef OLD_ICONV
+ typedef const char * iconv_ibp;
+#else
+ typedef char * iconv_ibp;
+#endif
char *reencode_string(const char *in, const char *out_encoding, const char *in_encoding)
{
iconv_t conv;
size_t insz, outsz, outalloc;
- char *out, *outpos, *cp;
+ char *out, *outpos;
+ iconv_ibp cp;
if (!in_encoding)
return NULL;
outalloc = outsz + 1; /* for terminating NUL */
out = xmalloc(outalloc);
outpos = out;
- cp = (char *)in;
+ cp = (iconv_ibp)in;
while (1) {
size_t cnt = iconv(conv, &cp, &insz, &outpos, &outsz);
int is_utf8(const char *text);
int is_encoding_utf8(const char *name);
-void print_wrapped_text(const char *text, int indent, int indent2, int len);
+int print_wrapped_text(const char *text, int indent, int indent2, int len);
#ifndef NO_ICONV
char *reencode_string(const char *in, const char *out_encoding, const char *in_encoding);