* Re: [PATCH 7/7] Implement git commit as a builtin command.
From: Kristian Høgsberg @ 2007-09-21 17:18 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vk5qmm8hq.fsf@gitster.siamese.dyndns.org>
On Wed, 2007-09-19 at 18:27 -0700, Junio C Hamano wrote:
> Kristian Høgsberg <krh@redhat.com> writes:
>
> > diff --git a/builtin-commit.c b/builtin-commit.c
> > new file mode 100644
> > index 0000000..ee98de9
> > --- /dev/null
> > +++ b/builtin-commit.c
> > @@ -0,0 +1,740 @@
> > +/*
> > + * Builtin "git commit"
> > + *
> > + * Copyright (c) 2007 Kristian Høgsberg <krh@redhat.com>
> > + * Based on git-commit.sh by Junio C Hamano and Linus Torvalds
> > + */
> > +
> > +#include <sys/types.h>
> > +#include <sys/stat.h>
> > +#include <unistd.h>
> > +
>
> With 85023577a8f4b540aa64aa37f6f44578c0c305a3 (simplify
> inclusion of system header files.), we introduced a rule against
> these lines. We probably would want a Coding Guideline (aka
> "Hacking Git") document somewhere.
Ok. I see you removed them in the pu commit, thanks.
> > +#include "cache.h"
> > +#include "cache-tree.h"
> > +#include "builtin.h"
> > +#include "diff.h"
> > +#include "diffcore.h"
> > +#include "commit.h"
> > +#include "revision.h"
> > +#include "wt-status.h"
> > +#include "run-command.h"
> > +#include "refs.h"
> > +#include "log-tree.h"
> > +#include "strbuf.h"
> > +#include "utf8.h"
> > +
> > +static const char builtin_commit_usage[] =
> > + "[-a | --interactive] [-s] [-v] [--no-verify] [-m <message> | -F <logfile> | (-C|-c) <commit> | --amend] [-u] [-e] [--author <author>] [--template <file>] [[-i | -o] <path>...]";
> > +
> > +static unsigned char head_sha1[20], merge_head_sha1[20];
> > +static char *use_message_buffer;
> > +static const char commit_editmsg[] = "COMMIT_EDITMSG";
> > +static struct lock_file lock_file;
> > +
> > +enum option_type {
> > + OPTION_NONE,
> > + OPTION_STRING,
> > + OPTION_INTEGER,
> > + OPTION_LAST,
> > +};
> > +
> > +struct option {
> > + enum option_type type;
> > + const char *long_name;
> > + char short_name;
> > + void *value;
> > +};
> > +
> > +static int scan_options(const char ***argv, struct option *options)
> > +{
> > + const char *value, *eq;
> > + int i;
> > +
> > + if (**argv == NULL)
> > + return 0;
> > + if ((**argv)[0] != '-')
> > + return 0;
> > + if (!strcmp(**argv, "--"))
> > + return 0;
> > +
> > + value = NULL;
> > + for (i = 0; options[i].type != OPTION_LAST; i++) {
> > + if ((**argv)[1] == '-') {
> > + if (!prefixcmp(options[i].long_name, **argv + 2)) {
> > + if (options[i].type != OPTION_NONE)
> > + value = *++(*argv);
> > + goto match;
> > + }
> > +
> > + eq = strchr(**argv + 2, '=');
> > + if (eq && options[i].type != OPTION_NONE &&
> > + !strncmp(**argv + 2,
> > + options[i].long_name, eq - **argv - 2)) {
> > + value = eq + 1;
> > + goto match;
> > + }
> > + }
> > +
> > + if ((**argv)[1] == options[i].short_name) {
> > + if ((**argv)[2] == '\0') {
> > + if (options[i].type != OPTION_NONE)
> > + value = *++(*argv);
> > + goto match;
> > + }
> > +
> > + if (options[i].type != OPTION_NONE) {
> > + value = **argv + 2;
> > + goto match;
> > + }
> > + }
> > + }
>
> How do you disambiguate between "--author <me>" and "--amend"?
> "The order in *options list matters" is an acceptable answer but
> it needs to be documented.
Yes, the order matters. I made sure the C version has the same
precedence as the shell script. I'll add a comment in parse-options.h.
> > +
> > + usage(builtin_commit_usage);
> > +
> > + match:
> > + switch (options[i].type) {
> > + case OPTION_NONE:
> > + *(int *)options[i].value = 1;
> > + break;
> > + case OPTION_STRING:
> > + if (value == NULL)
> > + die("option %s requires a value.", (*argv)[-1]);
> > + *(const char **)options[i].value = value;
> > + break;
> > + case OPTION_INTEGER:
> > + if (value == NULL)
> > + die("option %s requires a value.", (*argv)[-1]);
> > + *(int *)options[i].value = atoi(value);
> > + break;
> > + default:
> > + assert(0);
> > + }
> > +
> > + (*argv)++;
> > +
> > + return 1;
> > +}
>
> I do not particularly like this OPTION_LAST convention, but that
> is a minor detail. I also suspect in the longer term we might
> be better off using getopt() or popt(), but that would be a
> larger project.
>
> In any case, if you want to use this option parser, you would
> need to add a new file, perhaps parse_options.c, and move this
> part there, so that other parts of the system can reuse it.
I'll split it out in parse-options.[ch]. I still don't understand why
using getopt is better; parse-options.c is a 75 line file and it's
simple code. It does more work that getopt, since for most options it
automatically writes back the option argument into a global. All I have
to do then is validate that no illegal combination of options was
passed.
> And the same comment goes for the launch_editor still in
> builtin-tag.c. We should move it to editor.c or something.
Yeah.
> > +
> > +static char *logfile, *force_author, *message, *template_file;
> > +static char *edit_message, *use_message;
> > +static int all, edit_flag, also, interactive, only, no_verify, amend, signoff;
> > +static int quiet, verbose, untracked_files;
> > +
> > +static int no_edit, initial_commit, in_merge;
> > +const char *only_include_assumed;
> > +
> > +static struct option commit_options[] = {
> > + { OPTION_STRING, "file", 'F', (void *) &logfile },
> > + { OPTION_NONE, "all", 'a', &all },
> > + { OPTION_STRING, "author", 0, (void *) &force_author },
> > + { OPTION_NONE, "edit", 'e', &edit_flag },
>
> Why do some get casted to (void*) and others don't? It doesn't
> seem to have any pattern. I am puzzled...
Yes, oops, not sure what that was about.
> > + { OPTION_NONE, "include", 'i', &also },
> > + { OPTION_NONE, "interactive", 0, &interactive },
> > + { OPTION_NONE, "only", 'o', &only },
> > + { OPTION_STRING, "message", 'm', &message },
> > + { OPTION_NONE, "no-verify", 'n', &no_verify },
> > + { OPTION_NONE, "amend", 0, &amend },
> > + { OPTION_STRING, "reedit-message", 'c', &edit_message },
> > + { OPTION_STRING, "reuse-message", 'C', &use_message },
> > + { OPTION_NONE, "signoff", 's', &signoff },
> > + { OPTION_NONE, "quiet", 'q', &quiet },
> > + { OPTION_NONE, "verbose", 'v', &verbose },
> > + { OPTION_NONE, "untracked-files", 0, &untracked_files },
> > + { OPTION_STRING, "template", 't', &template_file },
> > + { OPTION_LAST },
> > +};
> > +
> > +/* FIXME: Taken from builtin-add, should be shared. */
>
> You're darn right. I thought you have some other patch that
> touches builtin-add already...
Yeah, I'll fix that.
> > +
> > +static void update_callback(struct diff_queue_struct *q,
> > + struct diff_options *opt, void *cbdata)
> > +{
> > + int i, verbose;
> > +
> > + verbose = *((int *)cbdata);
> > + for (i = 0; i < q->nr; i++) {
> > + struct diff_filepair *p = q->queue[i];
> > + const char *path = p->one->path;
> > + switch (p->status) {
> > + default:
> > + die("unexpacted diff status %c", p->status);
> > + case DIFF_STATUS_UNMERGED:
> > + case DIFF_STATUS_MODIFIED:
> > + case DIFF_STATUS_TYPE_CHANGED:
> > + add_file_to_cache(path, verbose);
> > + break;
> > + case DIFF_STATUS_DELETED:
> > + remove_file_from_cache(path);
> > + cache_tree_invalidate_path(active_cache_tree, path);
>
> I've updated remove_file_from_cache() to invalidate the path in
> cache-tree so this does not hurt but is no longer necessary. I
> removed this line in the version I queued in 'pu'.
>
> > + if (verbose)
> > + printf("remove '%s'\n", path);
> > + break;
> > + }
> > + }
> > +}
> > +
> > +static void
> > +add_files_to_cache(int fd, const char **files, const char *prefix)
> > +{
> > + struct rev_info rev;
> > +
> > + init_revisions(&rev, "");
> > + setup_revisions(0, NULL, &rev, NULL);
> > + rev.prune_data = get_pathspec(prefix, files);
> > + rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK;
> > + rev.diffopt.format_callback = update_callback;
> > + rev.diffopt.format_callback_data = &verbose;
> > +
> > + run_diff_files(&rev, 0);
> > + refresh_cache(REFRESH_QUIET);
>
> Your update_callback() does add_file_to_cache() which picks up
> the stat information from the filesystem already, so I do not
> see much point calling refresh_cache() afterwards. On the other
> hand, refreshing before running diff_files() might make sense,
> as you can avoid a lot of unnecessary work when you are told to
> do "git commit ."
I didn't have refresh_cache() in there originally, there was some test
case that didn't pass until I added it. The git-commit.sh shell script
calls git update-index --refresh after the prepare_index() part, which
is where I got it from. Will investigate.
> Have you tested this with an unmerged index?
Not yet.
> > +
> > + if (write_cache(fd, active_cache, active_nr) || close(fd))
> > + die("unable to write new index file");
> > +}
> > +
> > +static char *
> > +prepare_index(const char **files, const char *prefix)
> > +{
> > + int fd;
> > + struct tree *tree;
> > + struct lock_file *next_index_lock;
> > +
> > + fd = hold_locked_index(&lock_file, 1);
> > + if (read_cache() < 0)
> > + die("index file corrupt");
> > +
> > + if (all) {
> > + add_files_to_cache(fd, files, NULL);
> > + return lock_file.filename;
>
> Should you be passing files, which is used as pathspec to decide
> if your update_callback() should be called, under --all option?
Oh... hmm, if 'all' is set there are no paths, but yes, that is
confusing.
> > + } else if (also) {
> > + add_files_to_cache(fd, files, prefix);
> > + return lock_file.filename;
> > + }
> > +
> > + if (interactive)
> > + interactive_add();
>
> Don't you need to
>
> (1) abort if the user aborts out of interactive add with ^C?
> (2) re-read the index after interactive_add() returns?
Uhm, yes, good points.
> > + if (*files == NULL) {
> > + /* Commit index as-is. */
> > + rollback_lock_file(&lock_file);
> > + return get_index_file();
> > + }
> > +
> > + /*
> > + * FIXME: Warn on unknown files. Shell script does
> > + *
> > + * commit_only=`git-ls-files --error-unmatch -- "$@"`
> > + */
>
> This should be much easier to do than from the shell script, as
> you have active_cache[] (aka "the_index.cache[]") in-core.
>
> > + /*
> > + * FIXME: shell script does
> > + *
> > + * git-read-tree --index-output="$TMP_INDEX" -i -m HEAD
> > + *
> > + * which warns about unmerged files in the index.
> > + */
>
> I think "unmerged warning" is an unintended side effect. The
> point of the command is to have a copy of index, as there is no
> way for shell script to work with more than one index at a time
> without using a temporary file.
Yes, we talked about this in IRC a few weeks back, and agreed that just
read_tree() should be fine. I'll just remove that FIXME.
> > +
> > + /* update the user index file */
> > + add_files_to_cache(fd, files, prefix);
> > +
> > + if (!initial_commit) {
> > + tree = parse_tree_indirect(head_sha1);
> > + if (!tree)
> > + die("failed to unpack HEAD tree object");
> > + if (read_tree(tree, 0, NULL))
> > + die("failed to read HEAD tree object");
> > + }
>
> Huh? Doesn't this read_tree() defeat the add_files_to_cache()
> you did earlier?
This is the case where we add the files on the command line
to .git/index, but commit from a clean index file corresponding to HEAD
with the files from the command line added (partial commit?). The first
add_files_to_cache() updates .git/index, then we do read_tree() to build
a tmp index from HEAD and then we add the files again. The tmp index is
written to a tmp index file.
> > +
> > + /* Uh oh, abusing lock_file to create a garbage collected file */
> > + next_index_lock = xmalloc(sizeof(*next_index_lock));
> > + fd = hold_lock_file_for_update(next_index_lock,
> > + git_path("next-index-%d", getpid()), 1);
>
> That's not an abuse, but I wonder what happened to the fd you
> got at the beginning of the function.
Ugh, yeah, that's a bit ugly... it gets closed in add_files_to_cache()
once we've written the index. The patch I have here uses the
add_files_to_cache() from builtin-add.c which doesn't close the fd or
write the index. That now happens in prepare_index(), so it's a little
clearer what's going on.
> > + add_files_to_cache(fd, files, prefix);
>
> and then this is puzzling to me.
>
> I am starting to suspect that you might be better off if you do
> not follow the use of temporary index file that was in the shell
> script version to the letter. You can use more than one index
> in the core at the same time, now you are built-in.
As described above, we need to add the files to the user index and the
temporary index we're committing from. As for just using an in-memory
index, I wanted to do it that way originally, but you have to write it
to disk after all for the pre-commit hook. Maybe doing it in-memory is
better after all, and then only write it to disk if we actually have a
pre-commit hook.
> > +
> > + return next_index_lock->filename;
> > +}
>
> ... and if we were to go that route, wt_status structure would
> have a pointer to the "struct index_state" instead of the
> filename of the index... oops, wt_status_print() will discard
> and re-read the cache from file, so that approach would not work
> right now without fixing wt-status first. Hmm.
Yep, that was the other reason. I suppose a short term fix for this
would be to make run_status() take a struct index_state and write it to
a temp file and run against that. We can then clean that up to not use
a temp file in a second patch.
> > +static int run_status(FILE *fp, const char *index_file)
> > +{
> > + struct wt_status s;
> > +
> > + wt_status_prepare(&s);
> > +
> > + if (amend) {
> > + s.amend = 1;
> > + s.reference = "HEAD^1";
> > + }
> > + s.verbose = verbose;
> > + s.untracked = untracked_files;
> > + s.index_file = index_file;
> > + s.fp = fp;
> > +
> > + wt_status_print(&s);
> > +
> > + return s.commitable;
> > +}
>
> I did not look at the rest of the patch; it should be either
> obviously correct or outright incorrect --- anybody would notice
> the breakage immediately.
>
> The prepare_index() part is the most (and only) "interesting"
> part of the puzzle. I need to look at this again and think
> about it a bit more. It needs to:
>
> * save the current index and restore in case the whole
> "git-commit" is aborted in any way (e.g. ^C, empty log
> message from the editor); This is easy to do from C with
> hold_locked_index().
This is working in the current version. I use hold_locked_index() in
the beginning of prepare_index() and calls commit_locked_index() to
write the new index at the end of cmd_commit() once the commit is done.
> * when doing a partial commit,
> - read HEAD in a temporary index, if not initial commit;
> - update the temporary index with the given paths;
> - write out the temporary index as a tree to build a commit;
>
> - update the real index the same way with the given paths;
> - if all goes well, commit the updated real index; again,
> this is easy in C with commit_locked_index();
prepare_index() does this, that's the case you pointed out above, where
I'm calling add_files_to_cache() twice.
> * when not doing a partial commit,
> - update the real index with given paths (if "--also") or all
> what diff-files reports (if "--all");
> - write out the real index as a tree to build a commit;
> - if all goes well, commit the updated real index; again,
> this is easy in C with commit_locked_index();
This is also in prepare_index() - the 'if (all)' and 'if (also)' cases
in the beginning of the function does that, except commiting the the
updated real index, that's done at the end of cmd_commit(), share among
all cases.
> A thing to keep in mind is that you can write out the temporary
> index as a tree from the core without writing it out first to a
> temporary index file at all. Perhaps the code should be
> structured like this.
>
> - parse options and all the other necessary setup;
>
> - hold_locked_index() to lock the "real" index;
>
> - prepare_index() is responsibile for doing two things
>
> 1. build, write out and return the tree object to be
> committed;
>
> 2. leave the_index[] in the state to become the "real"
> index if this commit command is not aborted;
>
> - take the tree object, put commit log message around it and
> make a commit object;
>
> - commit_locked_index() to write out the "real" index.
>
> Now, the task #1 for prepare_index() is simpler for "also" and
> "all" case. You do the equivalent of "git-add -u" or "git add
> <path>" and run cache_tree_update() to write out the tree, and
> when you are done, both the_index.cache and the_index.cache_tree
> are up-to-date, ready to be written out by the caller at the
> very end.
Yes, but isn't that what the code is doing now? I write out the tree in
cmd_commit(), not in prepare_index(), but prepare_index() is also used
in cmd_status(). It seems better to only write the tree if we're going
to do a commit. Other than that, the flow of the code follows your
description pretty much step by step.
> For a partial commit, the task is a bit more convoluted, as
> writing out the tree needs to be done from outside the_index. I
> would say something like this:
>
> int prepare_index(unsigned char *sha1) {
> if (partial commit) {
> struct index_state tmp_index;
>
> /* "temporary index" only in-core */
> memset(&tmp_index, 0, sizeof(tmp_index));
> read_index(&tmp_index);
> add_files_to_index(files, prefix, &tmp_index);
> write_index_as_tree(&tmp_index, sha1);
> discard_index(&tmp_index);
>
> /* update the index the same way */
> add_files_to_index(files, prefix, &the_index);
> return ok;
> }
> /* otherwise */
> if (files && *files)
> add_files_to_index(files, prefix, &the_index);
> else if (all)
> add_files_to_index(NULL, prefix, &the_index);
> write_index_as_tree(&the_index, sha1);
> return ok;
> }
>
> where
>
> * add_files_to_index() is similar to your add_files_to_cache()
> but takes struct index_state; the callback can still diff
> with the_index.cache (aka active_cache) as that diff is what
> we are interested in updating anyway;
>
> * write_index_as_tree() would be a new function that takes
> struct index_state and writes that as a tree. It would
> essentially be the builtin-write-tree.c::write_tree()
> function except the opening and reading the index (or
> updating the cache-tree) part, something like:
>
> write_index_as_tree(struct index_state *istate, unsigned char *sha1)
> {
> if (!cache_tree_fully_valid(istate->cache_tree))
> cache_tree_update(istate->cache_tree,
> istate->cache,
> istate->cache_nr, 0, 0);
> hashcpy(sha1, istate->cache_tree->sha1);
> }
That looks nicer, the add_files_to_index() function is a pretty clean
solution. But again, we can't write the tree in prepare_index(); we
need the temporary index for the pre-commit hook, and prepare_index() is
used in cmd_status(). But we can just return an struct index_state
pointer from prepare_index().
Thanks for reviewing,
Kristian
^ permalink raw reply
* Re: Git as a filesystem
From: Dmitry Potapov @ 2007-09-21 17:29 UTC (permalink / raw)
To: Peter Stahlir; +Cc: Karl Hasselström, Johannes Schindelin, git
In-Reply-To: <fbe8b1780709210628u24c14117p5174bedb3d1912cb@mail.gmail.com>
On Fri, Sep 21, 2007 at 03:28:20PM +0200, Peter Stahlir wrote:
> Yes, but if there were deb and tar support in git (to automatically unpack
> archives and store the contents), together with the best available
> binary diffs I think the repository could be significantly smaller because
> files common to all architectures could be deltified,
You can unpack contain of gzipped or bzipped files and deltify it, but
you cannot restore exactly the same gzip or bzip file based on its
content unless you use exactly the same version of compressor that was
used to create the original file. So, if you put any .deb file in such
a system, you will get back a different .deb file (with a different SHA1).
So, aside high CPU and memory requirements, this system cannot work in
principle unless all users have exactly the same version of a compressor.
Dmitry
^ permalink raw reply
* Re: cvsimport bug on branches [was: conversion to git]
From: Robin Rosenberg @ 2007-09-21 17:15 UTC (permalink / raw)
To: Linus Torvalds
Cc: Steffen Prohaska, Eric Blake, m4-patches, Jim Meyering, git
In-Reply-To: <alpine.LFD.0.999.0709210840190.16478@woody.linux-foundation.org>
fredag 21 september 2007 skrev Linus Torvalds:
>
> On Fri, 21 Sep 2007, Steffen Prohaska wrote:
> >
> > Hard to say. The best is to avoid git-cvsimport if you need
> > to import branches correctly.
>
> Yes. git-cvsimport started out as a pretty quick hack, and depends on
> cvsps which is another fairly hacky thing.
>
> The big advantage of git-cvsimport is that it can do incremental imports,
> which I don't think the other methods do. But if there is any choice at
> all, and especially if you're not that interested in the incremental
> feature (ie you can cut over to git, and perhaps use git-cvsserver to
> "supprt" CVS users) the other CVS importers are likely to be much better.
fromcvs does incremental import and it's very fast and uses much less memory
than cvsimport. It needs the rcs files however and will not convert
non-branch tags.
-- robin
^ permalink raw reply
* Re: Git as a filesystem
From: Christian von Kietzell @ 2007-09-21 15:46 UTC (permalink / raw)
To: Peter Stahlir; +Cc: Nicolas Pitre, Johannes Schindelin, git
In-Reply-To: <fbe8b1780709210635l5803456aof3757418dc9653e7@mail.gmail.com>
Am Freitag, den 21.09.2007, 15:35 +0200 schrieb Peter Stahlir:
> > > I wonder how big a deltified Debian mirror in one pack file would be. :)
> >
> > It would be just as big as the non gitified storage on disk.
> >
> > The space saving with git comes from efficient delta storage of
> > _versioned_ files, i.e. multiple nearly identical versions of the same
> > file where the stored delta is only the small difference between the
> > first full version and subsequent versions. Unless you plan on storing
> > many different Debian versions together, you won't benefit from any
> > delta at all. And since Debian packages are already compressed, git
> > won't be able to compress them further.
> >
> > So don't waste your time.
>
> The 252GB stem from the fact that there are more than 10 architectures.
> I guess the /usr/share/doc of all architectures could be deltified (as could
> be all files that are architecture-independent)
>
> Right?
I don't think so. Architecture-independent files are usually separated
out into separate packages (think of the -doc and -data packages) that
get architecture "all" and land in the Debian archive only once. So you
probably won't save too much there.
Chris
^ permalink raw reply
* Re: cvsimport bug on branches [was: conversion to git]
From: Linus Torvalds @ 2007-09-21 15:42 UTC (permalink / raw)
To: Steffen Prohaska; +Cc: Eric Blake, m4-patches, Jim Meyering, git
In-Reply-To: <8D5EA3F4-9642-4604-963E-838D03650FBC@zib.de>
On Fri, 21 Sep 2007, Steffen Prohaska wrote:
>
> Hard to say. The best is to avoid git-cvsimport if you need
> to import branches correctly.
Yes. git-cvsimport started out as a pretty quick hack, and depends on
cvsps which is another fairly hacky thing.
The big advantage of git-cvsimport is that it can do incremental imports,
which I don't think the other methods do. But if there is any choice at
all, and especially if you're not that interested in the incremental
feature (ie you can cut over to git, and perhaps use git-cvsserver to
"supprt" CVS users) the other CVS importers are likely to be much better.
Linus
^ permalink raw reply
* Re: Git as a filesystem
From: jlh @ 2007-09-21 14:38 UTC (permalink / raw)
To: Peter Stahlir; +Cc: git
In-Reply-To: <fbe8b1780709210628u24c14117p5174bedb3d1912cb@mail.gmail.com>
Peter Stahlir wrote:
> But the thing is, I think there is a lot of redundancy in
> a) a Debian mirror or
Yes, surely. Your idea suggests that you want any file to be
reconstructed on-the-fly whenever it's being requested. Isn't
there the danger of killing performance, the CPU being the
bottleneck? I imagine such a debian mirror has quite some
traffic.
> b) your disk at home.
I doubt so. There sure is lots of redundancy within each file and
that's what compressed file systems are good for. But what you
talk about is redundancy across (unversioned) files, and I don't
feel there is a lot of it. Yes, I might have a few copies of the
file COPYING on my disk, and maybe some of my sources share a few
functions, but this won't save me tons of space. All my binaries,
libraries, MP3s, videos, config files, etc don't really have any
redundancy across file boundaries. And even if there is, finding
that redundancy is an O(whatever-but-not-n) operation that would
be rather slow.
I definitely see gitfs (or similar ideas) as potentially being
useful in some cases (maybe debian mirrors could be one), but not
for my disk at home, which I generally would prefer to be faster
than more compressed.
jlh
^ permalink raw reply
* [PATCH] Conjugate "search" correctly in the git-prune-packed man page.
From: Matt Kraai @ 2007-09-21 14:37 UTC (permalink / raw)
To: git; +Cc: Matt Kraai
Signed-off-by: Matt Kraai <kraai@ftbfs.org>
---
Documentation/git-prune-packed.txt | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/Documentation/git-prune-packed.txt b/Documentation/git-prune-packed.txt
index 3800edb..9f85f38 100644
--- a/Documentation/git-prune-packed.txt
+++ b/Documentation/git-prune-packed.txt
@@ -13,7 +13,7 @@ SYNOPSIS
DESCRIPTION
-----------
-This program search the `$GIT_OBJECT_DIR` for all objects that currently
+This program searches the `$GIT_OBJECT_DIR` for all objects that currently
exist in a pack file as well as the independent object directories.
All such extra objects are removed.
--
1.5.3.1
^ permalink raw reply related
* Re: Git as a filesystem
From: Miklos Vajna @ 2007-09-21 14:22 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Peter Stahlir, git
In-Reply-To: <Pine.LNX.4.64.0709211208440.28395@racer.site>
[-- Attachment #1: Type: text/plain, Size: 480 bytes --]
On Fri, Sep 21, 2007 at 12:11:41PM +0100, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> I haven't looked at it closely, but there is a GitFS:
>
> http://git.or.cz/gitwiki/InterfacesFrontendsAndTools#head-f354b40618742b976c13700fe1fea28387ad5c89
>
> (I am pointing you to the Git Wiki, so that you can find more pointers
> should you not be happy with this one.)
fyi, last time i had a look at it, it did not compile with git 1.5.2.x
thanks,
- VMiklos
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* [PATCH] Move the paragraph specifying where the .idx and .pack files should be
From: Matt Kraai @ 2007-09-21 13:43 UTC (permalink / raw)
To: git; +Cc: Matt Kraai
Signed-off-by: Matt Kraai <kraai@ftbfs.org>
---
Documentation/git-pack-objects.txt | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/Documentation/git-pack-objects.txt b/Documentation/git-pack-objects.txt
index 628f296..5237ab0 100644
--- a/Documentation/git-pack-objects.txt
+++ b/Documentation/git-pack-objects.txt
@@ -25,16 +25,16 @@ is efficient to access. The packed archive format (.pack) is
designed to be unpackable without having anything else, but for
random access, accompanied with the pack index file (.idx).
+Placing both in the pack/ subdirectory of $GIT_OBJECT_DIRECTORY (or
+any of the directories on $GIT_ALTERNATE_OBJECT_DIRECTORIES)
+enables git to read from such an archive.
+
'git-unpack-objects' command can read the packed archive and
expand the objects contained in the pack into "one-file
one-object" format; this is typically done by the smart-pull
commands when a pack is created on-the-fly for efficient network
transport by their peers.
-Placing both in the pack/ subdirectory of $GIT_OBJECT_DIRECTORY (or
-any of the directories on $GIT_ALTERNATE_OBJECT_DIRECTORIES)
-enables git to read from such an archive.
-
In a packed archive, an object is either stored as a compressed
whole, or as a difference from some other object. The latter is
often called a delta.
--
1.5.3.1
^ permalink raw reply related
* [PATCH] Use "" instead of "<unknown>" for placeholders [was Re: [PATCH] Added a new placeholder '%cm' for full commit message]
From: Michal Vitecek @ 2007-09-21 14:05 UTC (permalink / raw)
To: git
In-Reply-To: <Pine.LNX.4.64.0709211207070.28395@racer.site>
Johannes Schindelin wrote:
>On Fri, 21 Sep 2007, Michal Vitecek wrote:
>> Johannes Schindelin wrote:
>> >On Fri, 21 Sep 2007, Michal Vitecek wrote:
>> >
>> >> I have added a new placeholder '%cm' for a full commit message.
>> >
>> >You mean the raw message, including the headers? Why not use "%r" for
>> >that?
>>
>> No, sorry for the incorrect term. I meant the whole commit message
>> (subject + 2*\n + body).
>
>Ah, makes sense. In that case, "%M" maybe?
I think it's no longer needed if instead of "<undefined>" only "" will
be substituted.
>> >> I made it because I want to use my own pretty format which currently
>> >> only allows '%s' for subject and '%b' for body. But '%b' is
>> >> substituted with <undefined> if the body is "missing" which I
>> >> obviously don't like :)
>> >
>> >Then you should fix %b not to show "<undefined>".
>>
>> I'll do it if it is okay. Shall I do the same for the other
>> placeholders as well?
>
>Yeah. Don't know why I did it that way.
Here comes the big patch :)
>From 2e4ba4e73bbcd19558039dd85fe45c7bbe7fd1c4 Mon Sep 17 00:00:00 2001
From: Michal Vitecek <fuf@mageo.cz>
Date: Fri, 21 Sep 2007 14:40:37 +0200
Subject: [PATCH] Use "" instead of "<unknown>" for placeholders
---
commit.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/commit.c b/commit.c
index 99f65ce..7e90bc1 100644
--- a/commit.c
+++ b/commit.c
@@ -919,7 +919,7 @@ long format_commit_message(const struct commit *commit, const void *format,
table[IBODY].value = xstrdup(msg + i);
for (i = 0; i < ARRAY_SIZE(table); i++)
if (!table[i].value)
- interp_set_entry(table, i, "<unknown>");
+ interp_set_entry(table, i, "");
do {
char *buf = *buf_p;
--
1.5.3.1
--
fuf (fuf@mageo.cz)
^ permalink raw reply related
* Re: Git as a filesystem
From: Nicolas Pitre @ 2007-09-21 13:45 UTC (permalink / raw)
To: Peter Stahlir; +Cc: Johannes Schindelin, git
In-Reply-To: <fbe8b1780709210635l5803456aof3757418dc9653e7@mail.gmail.com>
On Fri, 21 Sep 2007, Peter Stahlir wrote:
> > > I wonder how big a deltified Debian mirror in one pack file would be. :)
> >
> > It would be just as big as the non gitified storage on disk.
> >
> > The space saving with git comes from efficient delta storage of
> > _versioned_ files, i.e. multiple nearly identical versions of the same
> > file where the stored delta is only the small difference between the
> > first full version and subsequent versions. Unless you plan on storing
> > many different Debian versions together, you won't benefit from any
> > delta at all. And since Debian packages are already compressed, git
> > won't be able to compress them further.
> >
> > So don't waste your time.
>
> The 252GB stem from the fact that there are more than 10 architectures.
> I guess the /usr/share/doc of all architectures could be deltified (as could
> be all files that are architecture-independent)
>
> Right?
Indeed.
But how much does this represents, once compressed, compared to the
rest? I doubt it is significant enough for the trouble.
Nicolas
^ permalink raw reply
* Re: Git as a filesystem
From: Michael Poole @ 2007-09-21 13:41 UTC (permalink / raw)
To: Peter Stahlir; +Cc: Karl Hasselström, Johannes Schindelin, git
In-Reply-To: <fbe8b1780709210628u24c14117p5174bedb3d1912cb@mail.gmail.com>
Peter Stahlir writes:
> Telling git to handle -for example- deb archives and storing
> everything in a pack file would take advantage of redundancy across
> _all_ files.
> So the /usr/share/doc of all architectures could be compressed.
>
> Right?
You're proposing to trade off lots of CPU time in fetching many files
from a pack and making the package file -- paid every time someone
requests a package -- for at most 250 GB of space (cf Amdahl's law).
How long are your users willing to wait in exchange for 250 GB of
saved space? How much CPU are you willing to spend for it? Compare
those to the cost of a 300 GB hard drive (roughly $65).
There's also the cost to make git support the package format, and to
maintain that code going forward. Those costs are also large.
Michael Poole
^ permalink raw reply
* [PATCH] new test from the submodule chapter of the user manual
From: Miklos Vajna @ 2007-09-21 13:09 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Johannes Schindelin, J. Bruce Fields
In-Reply-To: <7vd4wdkokn.fsf@gitster.siamese.dyndns.org>
Signed-off-by: Miklos Vajna <vmiklos@frugalware.org>
---
second version, now checking for all output, the commit hashes shows what is
committed is what we wanted to commit.
t/t3060-subprojects-tutorial.sh | 151 +++++++++++++++++++++++++++++++++++++++
1 files changed, 151 insertions(+), 0 deletions(-)
create mode 100755 t/t3060-subprojects-tutorial.sh
diff --git a/t/t3060-subprojects-tutorial.sh b/t/t3060-subprojects-tutorial.sh
new file mode 100755
index 0000000..fc09451
--- /dev/null
+++ b/t/t3060-subprojects-tutorial.sh
@@ -0,0 +1,151 @@
+#!/bin/sh
+#
+# Copyright (c) 2007 Miklos Vajna
+#
+
+test_description='A simple subprojects tutorial in the form of a test case'
+
+. ./test-lib.sh
+
+test_tick
+
+cat > create.expect << EOF
+Initialized empty Git repository in .git/
+Created initial commit 85349d2: Initial commit, submodule a
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+ create mode 100644 a.txt
+Initialized empty Git repository in .git/
+Created initial commit 47398d6: Initial commit, submodule b
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+ create mode 100644 b.txt
+Initialized empty Git repository in .git/
+Created initial commit 3d88526: Initial commit, submodule c
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+ create mode 100644 c.txt
+Initialized empty Git repository in .git/
+Created initial commit 73af3de: Initial commit, submodule d
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+ create mode 100644 d.txt
+EOF
+
+for i in a b c d
+do
+ mkdir $i &&
+ cd $i &&
+ git init &&
+ echo "module $i" > $i.txt &&
+ git add $i.txt &&
+ git commit -m "Initial commit, submodule $i" &&
+ cd ..
+done > create.output
+test_expect_success "create the submodules" 'cmp create.expect create.output'
+
+mkdir super
+cd super
+cat > create-super.expect << EOF
+Initialized empty Git repository in .git/
+Initialized empty Git repository in `pwd`/a/.git/
+0 blocks
+Initialized empty Git repository in `pwd`/b/.git/
+0 blocks
+Initialized empty Git repository in `pwd`/c/.git/
+0 blocks
+Initialized empty Git repository in `pwd`/d/.git/
+0 blocks
+EOF
+
+(git init &&
+for i in a b c d
+do
+ git submodule add `pwd`/../$i
+done ) &> create-super.output
+test_expect_success "create the superproject" 'cmp create-super.expect create-super.output'
+
+cat > commit-superproject.expect << EOF
+Created initial commit c496be9: Add submodules a, b, c and d.
+ 5 files changed, 16 insertions(+), 0 deletions(-)
+ create mode 100644 .gitmodules
+ create mode 160000 a
+ create mode 160000 b
+ create mode 160000 c
+ create mode 160000 d
+EOF
+git commit -m "Add submodules a, b, c and d." > commit-superproject.output
+
+test_expect_success "commit in the superproject" 'cmp commit-superproject.expect commit-superproject.output'
+
+cd ..
+
+cat > clone.expect << EOF
+Initialized empty Git repository in `pwd`/cloned/.git/
+0 blocks
+EOF
+
+git clone super cloned &> clone.output
+
+test_expect_success "clone the superproject" 'cmp clone.expect clone.output'
+
+cd cloned
+
+cat > submodule-init.expect << EOF
+Submodule 'a' (${PWD%%/cloned}/a/.git) registered for path 'a'
+Submodule 'b' (${PWD%%/cloned}/b/.git) registered for path 'b'
+Submodule 'c' (${PWD%%/cloned}/c/.git) registered for path 'c'
+Submodule 'd' (${PWD%%/cloned}/d/.git) registered for path 'd'
+EOF
+
+git submodule init > submodule-init.output
+
+test_expect_success "submodule init" 'cmp submodule-init.expect submodule-init.output'
+
+cat > submodule-update.expect << EOF
+Initialized empty Git repository in `pwd`/a/.git/
+0 blocks
+Submodule path 'a': checked out '85349d24595f581f5548b321a55c8a5fbe87259f'
+Initialized empty Git repository in `pwd`/b/.git/
+0 blocks
+Submodule path 'b': checked out '47398d6286153d23bfd5780ae3bf1996eb18cf90'
+Initialized empty Git repository in `pwd`/c/.git/
+0 blocks
+Submodule path 'c': checked out '3d88526ff6973dd27a07f57a3bb2bf5fa0bada42'
+Initialized empty Git repository in `pwd`/d/.git/
+0 blocks
+Submodule path 'd': checked out '73af3de6718291404ef541f4bb152f87d35a1481'
+EOF
+
+git submodule update &> submodule-update.output
+
+test_expect_success "submodule update" 'cmp submodule-update.expect submodule-update.output'
+
+cat > submodule-push.expect << EOF
+Created commit ab78b5a: Updated the submodule from within the superproject.
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+Everything up-to-date
+Created commit 8bbfffe: Updated submodule a.
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+updating 'refs/heads/master'
+ from c496be9e726d5c6ee0f96668b1b5822cf6cad027
+ to 8bbfffe1651b896e371bf7a3506452d545cf81b3
+ Also local refs/remotes/origin/master
+Generating pack...
+Done counting 2 objects.
+Deltifying 2 objects...
+ 50% (1/2) done
100% (2/2) done
+Writing 2 objects...
+ 50% (1/2) done
100% (2/2) done
+Total 2 (delta 0), reused 0 (delta 0)
+refs/heads/master: c496be9e726d5c6ee0f96668b1b5822cf6cad027 -> 8bbfffe1651b896e371bf7a3506452d545cf81b3
+EOF
+
+( cd a &&
+echo "adding a line again" >> a.txt &&
+git commit -a -m "Updated the submodule from within the superproject." &&
+git push &&
+cd .. &&
+git add a &&
+git commit -m "Updated submodule a." &&
+git push) &> submodule-push.output
+
+test_expect_success "update the submodule from within the superproject" 'cmp submodule-push.expect submodule-push.output'
+
+test_done
--
1.5.3.2.80.g077d6f-dirty
^ permalink raw reply related
* Re: Git as a filesystem
From: Peter Stahlir @ 2007-09-21 13:35 UTC (permalink / raw)
To: Nicolas Pitre; +Cc: Johannes Schindelin, git
In-Reply-To: <alpine.LFD.0.9999.0709210912120.32185@xanadu.home>
> > I wonder how big a deltified Debian mirror in one pack file would be. :)
>
> It would be just as big as the non gitified storage on disk.
>
> The space saving with git comes from efficient delta storage of
> _versioned_ files, i.e. multiple nearly identical versions of the same
> file where the stored delta is only the small difference between the
> first full version and subsequent versions. Unless you plan on storing
> many different Debian versions together, you won't benefit from any
> delta at all. And since Debian packages are already compressed, git
> won't be able to compress them further.
>
> So don't waste your time.
The 252GB stem from the fact that there are more than 10 architectures.
I guess the /usr/share/doc of all architectures could be deltified (as could
be all files that are architecture-independent)
Right?
^ permalink raw reply
* Re: [PATCH 4/4] t6000lib: workaround a possible dash bug
From: Herbert Xu @ 2007-09-21 13:28 UTC (permalink / raw)
To: Eric Wong; +Cc: Junio C Hamano, git
In-Reply-To: <11486091792604-git-send-email-normalperson@yhbt.net>
Hi Eric:
On Thu, May 25, 2006 at 07:06:18PM -0700, Eric Wong wrote:
> pdksh doesn't need this patch, of course bash works fine since
> that what most users use.
>
> Normally, 'var=val command' seems to work fine with dash, but
> perhaps there's something weird going on with "$@". dash is
> pretty widespread, so it'll be good to support this even though
> it does seem like a bug in dash.
Just going through dash issues right now. Do you recall
what the bug is in this case? Doing a quick test doesn't
seem to show much:
dash -c 'set -- env; a=b "$@"'
> diff --git a/t/t6000lib.sh b/t/t6000lib.sh
> index c6752af..d402621 100755
> --- a/t/t6000lib.sh
> +++ b/t/t6000lib.sh
> @@ -69,7 +69,9 @@ on_committer_date()
> {
> _date=$1
> shift 1
> - GIT_COMMITTER_DATE=$_date "$@"
> + export GIT_COMMITTER_DATE="$_date"
> + "$@"
> + unset GIT_COMMITTER_DATE
> }
>
> # Execute a command and suppress any error output.
> --
> 1.3.2.g7d11
Thanks,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: Git as a filesystem
From: Peter Stahlir @ 2007-09-21 13:28 UTC (permalink / raw)
To: Karl Hasselström; +Cc: Johannes Schindelin, git
In-Reply-To: <20070921125337.GA28456@diana.vm.bytemark.co.uk>
> > I wonder how big a deltified Debian mirror in one pack file would
> > be. :)
>
> Very, very close to 252 GB, since .deb files are already compressed.
Yes, but if there were deb and tar support in git (to automatically unpack
archives and store the contents), together with the best available
binary diffs I think the repository could be significantly smaller because
files common to all architectures could be deltified,
I did a quick check with 100MB of deb archives; the result was nearly 100MB
as you said.
I also did a quick check with all .so files in my /usr/lib directory; it shrunk
from 50MB to 20MB, the same is achieved with tar + bz2.
But the thing is, I think there is a lot of redundancy in
a) a Debian mirror or
b) your disk at home.
Telling git to handle -for example- deb archives and storing
everything in a pack file would take advantage of redundancy across
_all_ files.
So the /usr/share/doc of all architectures could be compressed.
Right?
^ permalink raw reply
* Re: Git as a filesystem
From: Nicolas Pitre @ 2007-09-21 13:22 UTC (permalink / raw)
To: Peter Stahlir; +Cc: Johannes Schindelin, git
In-Reply-To: <fbe8b1780709210441n281248dbh5ba9934d09d6bbfc@mail.gmail.com>
On Fri, 21 Sep 2007, Peter Stahlir wrote:
> This is was I was looking for. My motivation is whether it is possible
> to run a system, for example Debian on a computer on top of gitfs,
> and then have a huge mirror on it, for example a complete 252GB
> Debian mirror as space efficient as possible.
>
> I wonder how big a deltified Debian mirror in one pack file would be. :)
It would be just as big as the non gitified storage on disk.
The space saving with git comes from efficient delta storage of
_versioned_ files, i.e. multiple nearly identical versions of the same
file where the stored delta is only the small difference between the
first full version and subsequent versions. Unless you plan on storing
many different Debian versions together, you won't benefit from any
delta at all. And since Debian packages are already compressed, git
won't be able to compress them further.
So don't waste your time.
Nicolas
^ permalink raw reply
* Re: Git as a filesystem
From: Karl Hasselström @ 2007-09-21 12:53 UTC (permalink / raw)
To: Peter Stahlir; +Cc: Johannes Schindelin, git
In-Reply-To: <fbe8b1780709210441n281248dbh5ba9934d09d6bbfc@mail.gmail.com>
On 2007-09-21 13:41:07 +0200, Peter Stahlir wrote:
> My motivation is whether it is possible to run a system, for example
> Debian on a computer on top of gitfs, and then have a huge mirror on
> it, for example a complete 252GB Debian mirror as space efficient as
> possible.
>
> I wonder how big a deltified Debian mirror in one pack file would
> be. :)
Very, very close to 252 GB, since .deb files are already compressed.
If it's just the gzip compression you want, surely there must be real
filesystems that can do that.
--
Karl Hasselström, kha@treskal.com
www.treskal.com/kalle
^ permalink raw reply
* Re: Git as a filesystem
From: Peter Stahlir @ 2007-09-21 11:41 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0709211208440.28395@racer.site>
2007/9/21, Johannes Schindelin <Johannes.Schindelin@gmx.de>:
> On Fri, 21 Sep 2007, Peter Stahlir wrote:
>
> > Is it possible/feasible to use git as a filesystem?
> > Like having git on top of ext3.
>
> I haven't looked at it closely, but there is a GitFS:
>
> http://git.or.cz/gitwiki/InterfacesFrontendsAndTools#head-f354b40618742b976c13700fe1fea28387ad5c89
>
> (I am pointing you to the Git Wiki, so that you can find more pointers
> should you not be happy with this one.)
Thank you.
This is was I was looking for. My motivation is whether it is possible
to run a system, for example Debian on a computer on top of gitfs,
and then have a huge mirror on it, for example a complete 252GB
Debian mirror as space efficient as possible.
I wonder how big a deltified Debian mirror in one pack file would be. :)
Peter
^ permalink raw reply
* Re: Git as a filesystem
From: Johannes Schindelin @ 2007-09-21 11:11 UTC (permalink / raw)
To: Peter Stahlir; +Cc: git
In-Reply-To: <fbe8b1780709210351x30775090ldab559f25c27645d@mail.gmail.com>
Hi,
On Fri, 21 Sep 2007, Peter Stahlir wrote:
> Is it possible/feasible to use git as a filesystem?
> Like having git on top of ext3.
I haven't looked at it closely, but there is a GitFS:
http://git.or.cz/gitwiki/InterfacesFrontendsAndTools#head-f354b40618742b976c13700fe1fea28387ad5c89
(I am pointing you to the Git Wiki, so that you can find more pointers
should you not be happy with this one.)
Ciao,
Dscho
^ permalink raw reply
* Re: [PATCH] Added a new placeholder '%cm' for full commit message
From: Johannes Schindelin @ 2007-09-21 11:08 UTC (permalink / raw)
To: Michal Vitecek; +Cc: git
In-Reply-To: <20070921110646.GA9072@mageo.cz>
Hi,
On Fri, 21 Sep 2007, Michal Vitecek wrote:
> Johannes Schindelin wrote:
> >On Fri, 21 Sep 2007, Michal Vitecek wrote:
> >
> >> I have added a new placeholder '%cm' for a full commit message.
> >
> >You mean the raw message, including the headers? Why not use "%r" for
> >that?
>
> No, sorry for the incorrect term. I meant the whole commit message
> (subject + 2*\n + body).
Ah, makes sense. In that case, "%M" maybe?
> >> I made it because I want to use my own pretty format which currently
> >> only allows '%s' for subject and '%b' for body. But '%b' is
> >> substituted with <undefined> if the body is "missing" which I
> >> obviously don't like :)
> >
> >Then you should fix %b not to show "<undefined>".
>
> I'll do it if it is okay. Shall I do the same for the other
> placeholders as well?
Yeah. Don't know why I did it that way.
> >And please adher to the tips in Documentation/SubmittingPatches.
>
> Will do, sorry about the attachment - still learning :)
No problem. Thanks for contributing!
Ciao,
Dscho
^ permalink raw reply
* Re: [PATCH] Added a new placeholder '%cm' for full commit message
From: Michal Vitecek @ 2007-09-21 11:06 UTC (permalink / raw)
To: git
In-Reply-To: <Pine.LNX.4.64.0709211146090.28395@racer.site>
Johannes Schindelin wrote:
>On Fri, 21 Sep 2007, Michal Vitecek wrote:
>
>> I have added a new placeholder '%cm' for a full commit message.
>
>You mean the raw message, including the headers? Why not use "%r" for
>that?
No, sorry for the incorrect term. I meant the whole commit message
(subject + 2*\n + body).
>> I made it because I want to use my own pretty format which currently
>> only allows '%s' for subject and '%b' for body. But '%b' is substituted
>> with <undefined> if the body is "missing" which I obviously don't like
>> :)
>
>Then you should fix %b not to show "<undefined>".
I'll do it if it is okay. Shall I do the same for the other
placeholders as well?
>And please adher to the tips in Documentation/SubmittingPatches.
Will do, sorry about the attachment - still learning :)
Thank you,
Michal
--
fuf (fuf@mageo.cz)
^ permalink raw reply
* Git as a filesystem
From: Peter Stahlir @ 2007-09-21 10:51 UTC (permalink / raw)
To: git
Hi!
Is it possible/feasible to use git as a filesystem?
Like having git on top of ext3.
This way I could do a gitfs-gc and there is only one
pack file sitting on the disk which is a compressed
version of the whole system.
I am not interested in a version controlled filesystem,
only in the space saving aspects.
Thanks,
Peter
^ permalink raw reply
* Re: [PATCH] Added a new placeholder '%cm' for full commit message
From: Johannes Schindelin @ 2007-09-21 10:47 UTC (permalink / raw)
To: Michal Vitecek; +Cc: git
In-Reply-To: <20070921101420.GD22869@mageo.cz>
Hi,
On Fri, 21 Sep 2007, Michal Vitecek wrote:
> I have added a new placeholder '%cm' for a full commit message.
You mean the raw message, including the headers? Why not use "%r" for
that?
> I made it because I want to use my own pretty format which currently
> only allows '%s' for subject and '%b' for body. But '%b' is substituted
> with <undefined> if the body is "missing" which I obviously don't like
> :)
Then you should fix %b not to show "<undefined>".
And please adher to the tips in Documentation/SubmittingPatches.
Thank you,
Dscho
^ permalink raw reply
* [PATCH] Added a new placeholder '%cm' for full commit message
From: Michal Vitecek @ 2007-09-21 10:14 UTC (permalink / raw)
To: git
[-- Attachment #1: Type: text/plain, Size: 377 bytes --]
Hello,
I have added a new placeholder '%cm' for a full commit message. I made
it because I want to use my own pretty format which currently only
allows '%s' for subject and '%b' for body. But '%b' is substituted with
<undefined> if the body is "missing" which I obviously don't like :)
Thanks for consideration,
Michal
--
fuf (fuf@mageo.cz)
[-- Attachment #2: 0001-Added-a-new-placeholder-cm-for-full-commit-messag.patch --]
[-- Type: text/plain, Size: 2764 bytes --]
>From 5e22a989e6805d860b8477393fa8a6cc54f35193 Mon Sep 17 00:00:00 2001
From: Michal Vitecek <fuf@mageo.cz>
Date: Fri, 21 Sep 2007 12:02:57 +0200
Subject: [PATCH] Added a new placeholder '%cm' for full commit message
---
Documentation/pretty-formats.txt | 1 +
commit.c | 18 +++++++++++++++++-
2 files changed, 18 insertions(+), 1 deletions(-)
diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt
index 0193c3c..26c42d3 100644
--- a/Documentation/pretty-formats.txt
+++ b/Documentation/pretty-formats.txt
@@ -117,6 +117,7 @@ The placeholders are:
- '%e': encoding
- '%s': subject
- '%b': body
+- '%cm': commit message
- '%Cred': switch color to red
- '%Cgreen': switch color to green
- '%Cblue': switch color to blue
diff --git a/commit.c b/commit.c
index 99f65ce..1e24e21 100644
--- a/commit.c
+++ b/commit.c
@@ -814,6 +814,7 @@ long format_commit_message(const struct commit *commit, const void *format,
{ "%e" }, /* encoding */
{ "%s" }, /* subject */
{ "%b" }, /* body */
+ { "%cm" }, /* commit message (subject and body) */
{ "%Cred" }, /* red */
{ "%Cgreen" }, /* green */
{ "%Cblue" }, /* blue */
@@ -835,12 +836,14 @@ long format_commit_message(const struct commit *commit, const void *format,
IENCODING,
ISUBJECT,
IBODY,
+ ICOMMIT_MESSAGE,
IRED, IGREEN, IBLUE, IRESET_COLOR,
INEWLINE,
ILEFT_RIGHT,
};
struct commit_list *p;
char parents[1024];
+ int cm_len = 0;
int i;
enum { HEADER, SUBJECT, BODY } state;
const char *msg = commit->buffer;
@@ -897,6 +900,7 @@ long format_commit_message(const struct commit *commit, const void *format,
if (state == SUBJECT) {
table[ISUBJECT].value = xstrndup(msg + i, eol - i);
+ cm_len = eol - i + 2; /* + 2 for 2 newlines */
i = eol;
}
if (i == eol) {
@@ -915,8 +919,20 @@ long format_commit_message(const struct commit *commit, const void *format,
xstrndup(msg + i + 9, eol - i - 9);
i = eol;
}
- if (msg[i])
+ if (msg[i]) {
table[IBODY].value = xstrdup(msg + i);
+ cm_len += strlen(msg + i);
+ }
+ if (cm_len) {
+ table[ICOMMIT_MESSAGE].value = xmalloc(cm_len + 1);
+ table[ICOMMIT_MESSAGE].value[0] = '\0';
+ if (table[ISUBJECT].value) {
+ strcpy(table[ICOMMIT_MESSAGE].value, table[ISUBJECT].value);
+ strcat(table[ICOMMIT_MESSAGE].value, "\n\n");
+ }
+ if (table[IBODY].value)
+ strcat(table[ICOMMIT_MESSAGE].value, table[IBODY].value);
+ }
for (i = 0; i < ARRAY_SIZE(table); i++)
if (!table[i].value)
interp_set_entry(table, i, "<unknown>");
--
1.5.3.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox