Git development
 help / color / mirror / Atom feed
* Re: Mercurial 0.4e vs git network pull
From: Petr Baudis @ 2005-05-15  8:54 UTC (permalink / raw)
  To: Matt Mackall; +Cc: linux-kernel, git, mercurial, Linus Torvalds
In-Reply-To: <20050512205735.GE5914@waste.org>

Dear diary, on Thu, May 12, 2005 at 10:57:35PM CEST, I got a letter
where Matt Mackall <mpm@selenic.com> told me that...
> Does this need an HTTP request (and round trip) per object? It appears
> to. That's 2200 requests/round trips for my 800 patch benchmark.

Yes it does. On the other side, it needs no server-side CGI. But I guess
it should be pretty easy to write some kind of server-side CGI streamer,
and it would then easily take just a single HTTP request (telling the
server the commit ID and receiving back all the objects).

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
C++: an octopus made by nailing extra legs onto a dog. -- Steve Taylor

^ permalink raw reply

* [PATCH] Implement git-checkout-cache -u to update stat information in the cache.
From: Junio C Hamano @ 2005-05-15  8:36 UTC (permalink / raw)
  To: pasky; +Cc: git, torvalds

With -u flag, git-checkout-cache picks up the stat information
from newly created files and updates the cache.  This removes the
need to run git-update-cache --refresh immediately after running
git-checkout-cache.

Signed-off-by: Junio C Hamano <junkio@cox.net>
---

Documentation/git-checkout-cache.txt |    6 +++
Makefile                             |    2 -
cache.h                              |    9 +++++
checkout-cache.c                     |   35 ++++++++++++++++++++-
index.c                              |   58 +++++++++++++++++++++++++++++++++++
read-cache.c                         |   20 ++++++++++++
t/t2002-checkout-cache-u.sh          |   35 +++++++++++++++++++++
update-cache.c                       |   48 ++--------------------------
8 files changed, 166 insertions(+), 47 deletions(-)
index.c (. --> 100644)
t/t0110-environment-names-old.sh (100644 --> 100755)
t/t1000-read-tree-m-3way.sh (100644 --> 100755)
t/t2002-checkout-cache-u.sh (. --> 100755)
t/t4000-diff-format.sh (100644 --> 100755)

--- a/Documentation/git-checkout-cache.txt
+++ b/Documentation/git-checkout-cache.txt
@@ -9,7 +9,7 @@
 
 SYNOPSIS
 --------
-'git-checkout-cache' [-q] [-a] [-f] [-n] [--prefix=<string>]
+'git-checkout-cache' [-u] [-q] [-a] [-f] [-n] [--prefix=<string>]
 	           [--] <file>...
 
 DESCRIPTION
@@ -19,6 +19,10 @@
 
 OPTIONS
 -------
+-u::
+	update stat information for the checked out entries in
+	the cache file.
+
 -q::
 	be quiet if files exist or are not in the cache
 
--- a/Makefile
+++ b/Makefile
@@ -36,7 +36,7 @@
 	$(INSTALL) $(PROG) $(SCRIPTS) $(dest)$(bin)
 
 LIB_OBJS=read-cache.o sha1_file.o usage.o object.o commit.o tree.o blob.o \
-	 tag.o date.o
+	 tag.o date.o index.o
 LIB_FILE=libgit.a
 LIB_H=cache.h object.h blob.h tree.h commit.h tag.h
 
--- a/cache.h
+++ b/cache.h
@@ -131,6 +131,15 @@
 extern int same_name(struct cache_entry *a, struct cache_entry *b);
 extern int cache_match_stat(struct cache_entry *ce, struct stat *st);
 extern int index_fd(unsigned char *sha1, int fd, struct stat *st);
+extern void fill_stat_cache_info(struct cache_entry *ce, struct stat *st);
+
+struct cache_file {
+	struct cache_file *next;
+	char lockfile[PATH_MAX];
+};
+extern int hold_index_file_for_update(struct cache_file *, const char *path);
+extern int commit_index_file(struct cache_file *);
+extern void rollback_index_file(struct cache_file *);
 
 #define MTIME_CHANGED	0x0001
 #define CTIME_CHANGED	0x0002
--- a/checkout-cache.c
+++ b/checkout-cache.c
@@ -36,7 +36,7 @@
 #include <dirent.h>
 #include "cache.h"
 
-static int force = 0, quiet = 0, not_new = 0;
+static int force = 0, quiet = 0, not_new = 0, refresh_cache = 0;
 
 static void create_directories(const char *path)
 {
@@ -154,6 +154,12 @@
 		free(new);
 		return error("checkout-cache: unknown file mode for %s", path);
 	}
+
+	if (refresh_cache) {
+		struct stat st;
+		lstat(ce->name, &st);
+		fill_stat_cache_info(ce, &st);
+	}
 	return 0;
 }
 
@@ -224,6 +230,8 @@
 {
 	int i, force_filename = 0;
 	const char *base_dir = "";
+	struct cache_file cache_file;
+	int newfd = -1;
 
 	if (read_cache() < 0) {
 		die("invalid cache");
@@ -252,12 +260,37 @@
 				not_new = 1;
 				continue;
 			}
+			if (!strcmp(arg, "-u")) {
+				refresh_cache = 1;
+				if (newfd < 0)
+					newfd = hold_index_file_for_update
+						(&cache_file,
+						 get_index_file());
+				if (newfd < 0)
+					die("cannot open index.lock file.");
+				continue;
+			}
 			if (!memcmp(arg, "--prefix=", 9)) {
 				base_dir = arg+9;
 				continue;
 			}
 		}
+		if (base_dir[0]) {
+			/* when --prefix is specified we do not
+			 * want to update cache.
+			 */
+			if (refresh_cache) {
+				close(newfd); newfd = -1;
+				rollback_index_file(&cache_file);
+			}
+			refresh_cache = 0;
+		}
 		checkout_file(arg, base_dir);
 	}
+
+	if (0 <= newfd &&
+	    (write_cache(newfd, active_cache, active_nr) ||
+	     commit_index_file(&cache_file)))
+		die("Unable to write new cachefile");
 	return 0;
 }
--- a/index.c
+++ b/index.c
@@ -0,0 +1,58 @@
+/*
+ * GIT - The information manager from hell
+ * Cache-file locking management.
+ *
+ * Copyright (c) 2005 Junio C Hamano.
+ */
+#include <signal.h>
+#include "cache.h"
+
+static struct cache_file *cache_file_list = NULL;
+
+static void remove_lock_file(void)
+{
+	while (cache_file_list) {
+		if (cache_file_list->lockfile[0])
+			unlink(cache_file_list->lockfile);
+		cache_file_list = cache_file_list->next;
+	}
+}
+
+static void remove_lock_file_on_signal(int signo)
+{
+	remove_lock_file();
+}
+
+int commit_index_file(struct cache_file *cf)
+{
+	int i;
+	char indexfile[PATH_MAX];
+
+	strcpy(indexfile, cf->lockfile);
+	i = strlen(indexfile);
+	indexfile[i - 5] = 0; /* .lock */
+	i = rename(cf->lockfile, indexfile);
+	cf->lockfile[0] = 0;
+	return i;
+}
+
+void rollback_index_file(struct cache_file *cf)
+{
+	unlink(cf->lockfile);
+	cf->lockfile[0] = 0;
+}
+
+int hold_index_file_for_update(struct cache_file *cf, const char *path)
+{
+	int newfd;
+
+	sprintf(cf->lockfile, "%s.lock", path);
+	cf->next = cache_file_list;
+	cache_file_list = cf;
+	newfd = open(cf->lockfile, O_RDWR | O_CREAT | O_EXCL, 0600);
+	if (!cf->next) {
+		signal(SIGINT, remove_lock_file_on_signal);
+		atexit(remove_lock_file);
+	}
+	return newfd;
+}
--- a/read-cache.c
+++ b/read-cache.c
@@ -9,6 +9,26 @@
 struct cache_entry **active_cache = NULL;
 unsigned int active_nr = 0, active_alloc = 0, active_cache_changed = 0;
 
+/*
+ * This only updates the "non-critical" parts of the directory
+ * cache, ie the parts that aren't tracked by GIT, and only used
+ * to validate the cache.
+ */
+void fill_stat_cache_info(struct cache_entry *ce, struct stat *st)
+{
+	ce->ce_ctime.sec = htonl(st->st_ctime);
+	ce->ce_mtime.sec = htonl(st->st_mtime);
+#ifdef NSEC
+	ce->ce_ctime.nsec = htonl(st->st_ctim.tv_nsec);
+	ce->ce_mtime.nsec = htonl(st->st_mtim.tv_nsec);
+#endif
+	ce->ce_dev = htonl(st->st_dev);
+	ce->ce_ino = htonl(st->st_ino);
+	ce->ce_uid = htonl(st->st_uid);
+	ce->ce_gid = htonl(st->st_gid);
+	ce->ce_size = htonl(st->st_size);
+}
+
 int cache_match_stat(struct cache_entry *ce, struct stat *st)
 {
 	unsigned int changed = 0;
--- a/t/t2002-checkout-cache-u.sh
+++ b/t/t2002-checkout-cache-u.sh
@@ -0,0 +1,35 @@
+#!/bin/sh
+#
+# Copyright (c) 2005 Junio C Hamano
+#
+
+test_description='git-checkout-cache -u test.
+
+With -u flag, git-checkout-cache internally runs the equivalent of
+git-update-cache --refresh on the checked out entry.'
+
+. ./test-lib.sh
+
+test_expect_success \
+'preparation' '
+echo frotz >path0 &&
+git-update-cache --add path0 &&
+t=$(git-write-tree)'
+
+test_expect_failure \
+'without -u, git-checkout-cache smudges stat information.' '
+rm -f path0 &&
+git-read-tree $t &&
+git-checkout-cache -f -a &&
+git-diff-files | diff - /dev/null'
+
+test_expect_success \
+'with -u, git-checkout-cache picks up stat information from new files.' '
+rm -f path0 &&
+git-read-tree $t &&
+git-checkout-cache -u -f -a &&
+git-diff-files | diff - /dev/null'
+
+
+
+
--- a/update-cache.c
+++ b/update-cache.c
@@ -3,7 +3,6 @@
  *
  * Copyright (C) Linus Torvalds, 2005
  */
-#include <signal.h>
 #include "cache.h"
 
 /*
@@ -31,26 +30,6 @@
 	return (unsigned long)ptr > (unsigned long)-1000L;
 }
 
-/*
- * This only updates the "non-critical" parts of the directory
- * cache, ie the parts that aren't tracked by GIT, and only used
- * to validate the cache.
- */
-static void fill_stat_cache_info(struct cache_entry *ce, struct stat *st)
-{
-	ce->ce_ctime.sec = htonl(st->st_ctime);
-	ce->ce_mtime.sec = htonl(st->st_mtime);
-#ifdef NSEC
-	ce->ce_ctime.nsec = htonl(st->st_ctim.tv_nsec);
-	ce->ce_mtime.nsec = htonl(st->st_mtim.tv_nsec);
-#endif
-	ce->ce_dev = htonl(st->st_dev);
-	ce->ce_ino = htonl(st->st_ino);
-	ce->ce_uid = htonl(st->st_uid);
-	ce->ce_gid = htonl(st->st_gid);
-	ce->ce_size = htonl(st->st_size);
-}
-
 static int add_file_to_cache(char *path)
 {
 	int size, namelen, option, status;
@@ -313,36 +292,17 @@
 	return add_cache_entry(ce, option);
 }
 
-static const char *lockfile_name = NULL;
-
-static void remove_lock_file(void)
-{
-	if (lockfile_name)
-		unlink(lockfile_name);
-}
-
-static void remove_lock_file_on_signal(int signo)
-{
-	remove_lock_file();
-}
+struct cache_file cache_file;
 
 int main(int argc, char **argv)
 {
 	int i, newfd, entries, has_errors = 0;
 	int allow_options = 1;
-	static char lockfile[MAXPATHLEN+1];
-	const char *indexfile = get_index_file();
-
-	snprintf(lockfile, sizeof(lockfile), "%s.lock", indexfile);
 
-	newfd = open(lockfile, O_RDWR | O_CREAT | O_EXCL, 0600);
+	newfd = hold_index_file_for_update(&cache_file, get_index_file());
 	if (newfd < 0)
 		die("unable to create new cachefile");
 
-	signal(SIGINT, remove_lock_file_on_signal);
-	atexit(remove_lock_file);
-	lockfile_name = lockfile;
-
 	entries = read_cache();
 	if (entries < 0)
 		die("cache corrupted");
@@ -401,9 +361,9 @@
 		if (add_file_to_cache(path))
 			die("Unable to add %s to database", path);
 	}
-	if (write_cache(newfd, active_cache, active_nr) || rename(lockfile, indexfile))
+	if (write_cache(newfd, active_cache, active_nr) ||
+	    commit_index_file(&cache_file))
 		die("Unable to write new cachefile");
 
-	lockfile_name = NULL;
 	return has_errors ? 1 : 0;
 }
------------------------------------------------


^ permalink raw reply

* Re: [PATCH cogito] "cg-whatsnew" command
From: Catalin Marinas @ 2005-05-15  8:29 UTC (permalink / raw)
  To: Petr Baudis; +Cc: git
In-Reply-To: <20050514110941.GB3905@pasky.ji.cz>

[-- Attachment #1: Type: text/plain, Size: 693 bytes --]

Petr Baudis <pasky@ucw.cz> wrote:
> Dear diary, on Sat, May 14, 2005 at 12:58:04PM CEST, I got a letter
> where Catalin Marinas <catalin.marinas@arm.com> told me that...
>> This patch adds a simple command that shows the unmerged changes on a
>> branch. I find it quite useful to be able to see the diff or the log
>> before merging (gnuarch has something similar with "missing").
>
> I'd prefer this to be functionality builtin to cg-log and cg-mkpatch.
> Perhaps some
>
> 	cg-log -m $branch2 [$branch1]
>
> to show stuff in branch2 not yet merged to branch1.

See the attached patch. Let me know if you want it implemented
differently. I also added the "-m" option to cg-diff.

-- 
Catalin


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: patch-m-option --]
[-- Type: text/x-patch, Size: 4489 bytes --]

"-m" option added to cg-diff, cg-log and cg-mkpatch

This option takes two optional parameters, branch2 and branch1, and shows
the changes in branch2 not yet merged to branch1. Branch2 defaults to
origin and branch1 to HEAD.

Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>

---
commit 1a9bf2d3a0478344ae4019ac0725426627c32658
tree 3e889a5c03d7df9f82d7a649e02fef2ebdbb9f75
parent fa6e9eb368e949e78c4e66217461cf624b52b0a2
author Catalin Marinas <cmarinas@pc1117.cambridge.arm.com> Sun, 15 May 2005 09:25:49 +0100
committer Catalin Marinas <cmarinas@pc1117.cambridge.arm.com> Sun, 15 May 2005 09:25:49 +0100

 cg-diff    |   19 +++++++++++++++++++
 cg-help    |    6 +++---
 cg-log     |   19 +++++++++++++++++++
 cg-mkpatch |   19 +++++++++++++++++++
 4 files changed, 60 insertions(+), 3 deletions(-)

Index: cg-diff
===================================================================
--- de641904363cd3759f132ee7c0dfaf8a2ee58388/cg-diff  (mode:100755)
+++ 3e889a5c03d7df9f82d7a649e02fef2ebdbb9f75/cg-diff  (mode:100755)
@@ -14,6 +14,9 @@
 # -p instead of one ID denotes a parent commit to the specified ID
 # (which must not be a tree, obviously).
 #
+# -m [branch2] [branch1] shows the changes in branch2 (defaulting to
+# origin) not yet merged to branch1 (defaulting to HEAD)
+#
 # Outputs a diff converting the first tree to the second one.
 
 . ${COGITO_LIB}cg-Xlib
@@ -31,6 +34,22 @@
 	parent=1
 fi
 
+if [ "$1" = "-m" ]; then
+	branch=HEAD
+	id2=origin
+	shift
+	if [ "$1" ]; then
+		id2=$1
+		shift
+	fi
+	if [ "$1" ]; then
+		branch=$1
+		shift
+	fi
+	id1=$(git-merge-base "$branch" "$id2")
+	[ "$id1" ] || die "Unable to determine the merge base"
+fi
+
 if [ "$1" = "-r" ]; then
 	shift
 	id1=$(echo "$1": | cut -d : -f 1)
Index: cg-help
===================================================================
--- de641904363cd3759f132ee7c0dfaf8a2ee58388/cg-help  (mode:100755)
+++ 3e889a5c03d7df9f82d7a649e02fef2ebdbb9f75/cg-help  (mode:100755)
@@ -26,14 +26,14 @@
 	cg-cancel
 	cg-clone	[-s] SOURCE_LOC [DESTDIR]
 	cg-commit	[-m"Commit message"]... [-e | -E] [FILE]... < log message
-	cg-diff		[-p] [-r FROM_ID[:TO_ID]] [FILE]...
+	cg-diff		[-p] [-r FROM_ID[:TO_ID]] [-m [BNAME] [BNAME]] [FILE]...
 	cg-export	DEST [TREE_ID]
 	cg-help		[COMMAND]
 	cg-init
-	cg-log		[-c] [-f] [-r FROM_ID[:TO_ID]] [FILE]...
+	cg-log		[-c] [-f] [-r FROM_ID[:TO_ID]] ] [-m [BNAME] [BNAME]] [FILE]...
 	cg-ls		[TREE_ID]
 	cg-merge	[-c] [-b BASE_ID] FROM_ID
-	cg-mkpatch	[-s] [-r FROM_ID[:TO_ID]]
+	cg-mkpatch	[-s] [-r FROM_ID[:TO_ID]]] [-m [BNAME] [BNAME]]
 	cg-patch			< patch on stdin
 	cg-pull		[BNAME]
 	cg-restore	[FILE]...
Index: cg-log
===================================================================
--- de641904363cd3759f132ee7c0dfaf8a2ee58388/cg-log  (mode:100755)
+++ 3e889a5c03d7df9f82d7a649e02fef2ebdbb9f75/cg-log  (mode:100755)
@@ -22,6 +22,9 @@
 # (HEAD by default), or id1:id2 representing an (id1;id2] range
 # of commits to show.
 #
+# -m [branch2] [branch1] shows the changes in branch2 (defaulting to
+# origin) not yet merged to branch1 (defaulting to HEAD)
+#
 # The rest of arguments are took as filenames; cg-log then displays
 # only changes in those files.
 
@@ -94,6 +97,22 @@
 
 log_start=
 log_end=
+if [ "$1" = "-m" ]; then
+	branch=HEAD
+	log_end=origin
+	shift
+	if [ "$1" ]; then
+		log_end=$1
+		shift
+	fi
+	if [ "$1" ]; then
+		branch=$1
+		shift
+	fi
+	log_start=$(git-merge-base "$branch" "$log_end")
+	[ "$log_start" ] || die "Unable to determine the merge base"
+fi
+
 if [ "$1" = "-r" ]; then
 	shift
 	log_start="$1"
Index: cg-mkpatch
===================================================================
--- de641904363cd3759f132ee7c0dfaf8a2ee58388/cg-mkpatch  (mode:100755)
+++ 3e889a5c03d7df9f82d7a649e02fef2ebdbb9f75/cg-mkpatch  (mode:100755)
@@ -9,6 +9,9 @@
 #
 # Takes an -r followed with ID defaulting to HEAD, or id1:id2, forming
 # a range (id1;id2]. (Use "id1:" to take just everything from id1 to HEAD.)
+#
+# -m [branch2] [branch1] shows the changes in branch2 (defaulting to
+# origin) not yet merged to branch1 (defaulting to HEAD)
 
 . ${COGITO_LIB}cg-Xlib
 
@@ -65,6 +68,22 @@
 
 log_start=
 log_end=
+if [ "$1" = "-m" ]; then
+	branch=HEAD
+	log_end=origin
+	shift
+	if [ "$1" ]; then
+		log_end=$1
+		shift
+	fi
+	if [ "$1" ]; then
+		branch=$1
+		shift
+	fi
+	log_start=$(git-merge-base "$branch" "$log_end")
+	[ "$log_start" ] || die "Unable to determine the merge base"
+fi
+
 if [ "$1" = "-r" ]; then
 	shift
 	log_start="$1"

^ permalink raw reply

* Re: [RFD] Ignore rules
From: Junio C Hamano @ 2005-05-15  6:52 UTC (permalink / raw)
  To: jon; +Cc: Petr Baudis, David Greaves, torvalds, GIT Mailing Lists
In-Reply-To: <7v4qd5vxao.fsf@assigned-by-dhcp.cox.net>

>>>>> "JCH" == Junio C Hamano <junkio@cox.net> writes:

JCH> ...  For example, in linux-2.6 git tree, you _ought_ to be
JCH> able to say something like this:

JCH>     cd fs
JCH>     find ext? ../include/linux -type f -print0 |
JCH>     git-path-helper -z |
JCH>     xargs -r -0 git-update-cache --add --

The above example has an obvious thinko/typo.  It should have
been like this:

     cd fs
     find ext? ../include/linux -type f -print0 |
     git-path-helper -z | {
         cd .. && xargs -r -0 git-update-cache --add --
     }


^ permalink raw reply

* Re: README rewrite
From: Wink Saville @ 2005-05-15  6:50 UTC (permalink / raw)
  Cc: git
In-Reply-To: <20050515044941.GB7391@tumblerings.org>

Zack Brown wrote:

 > Hi Petr,
 >
 > This patch is a complete rewrite of the Cogito section of the README file.
 > Commands are explained in detail, with a quickstart section at the top and a
 > full command reference below.
 >
 > Signed-off-by: Zack Brown <zbrown@tumblerings.org>
 >
 > README: needs update
 > Index: README
 > ===================================================================
 > --- 4ef3de6ae44888d83e8c00326ddcc9f40cbd12e2/README  (mode:100644)
 > +++ uncommitted/README  (mode:100644)
 > @@ -1,164 +1,656 @@
 > -	GIT - the stupid content tracker
 > +                Cogito
 >
 > -"git" can mean anything, depending on your mood.
 > +Cogito is a version control system layered on top of the git
 > +content-tracking filesystem. This document first describes some quick ways
 > +to get started using Cogito, then goes over each available command one by
 > +one.
 >
 > - - random three-letter combination that is pronounceable, and not
 > -   actually used by any common UNIX command.  The fact that it is a
 > -   mispronunciation of "get" may or may not be relevant.
 > - - stupid. contemptible and despicable. simple. Take your pick from the
 > -   dictionary of slang.
 > - - "global information tracker": you're in a good mood, and it actually

<snip>

 > +
 > + - random three-letter combination that is pronounceable, and not
 > +   actually used by any common UNIX command.  The fact that it is a
 > +   mispronunciation of "get" may or may not be relevant.
 > + - stupid. contemptible and despicable. simple. Take your pick from the
 > +   dictionary of slang.
 > + - "global information tracker": you're in a good mood, and it actually
 > +   works for you. Angels sing, and a light suddenly fills the room.
 > + - "goddamn idiotic truckload of sh*t": when it breaks
 > +
 > +The GIT itself is merely an extremely fast and flexible filesystem-based
 > +database designed to store directory trees with regard to their history.
 > +The top layer is a SCM-like tool Cogito which enables human beings to work
 > +with the database in a manner to a degree similar to other SCM tools (like
 > +CVS, BitKeeper or Monotone).
 > +
 > +Git is a stupid (but extremely fast) directory content manager.  It
 >  doesn't do a whole lot, but what it _does_ do is track directory
 >  contents efficiently.
 >
 >
 >

Zack,

Good improvements, especially for neophytes like me who don't read enough and get confused 
when cg-init has the word DEPRECATED in its help:)

Questions/Suggestions:

1) How do I actaully apply the patch supplied in the email, where readme.patch was the 
contents of the email. I tried as below, but that didn't work.

    wink@tuxws cogito-0.10 $ cg-patch < readme.patch
    patching file README
    patch unexpectedly ends in middle of line
    Hunk #1 FAILED at 1.
    1 out of 1 hunk FAILED -- saving rejects to file README.rej

I "read" the patch and would like to suggest some additional information regarding cg-pull 
and revisons. My understanding is that it pulls the new "change sets" from the "parent" to 
my repository. I then should be able to compare the differences as per:

   "Using cg-pull is useful for a variety of purposes, for instance if you want
    to construct a diff against the latest version of the upstream sources, but
    don't want those changes to disturb your ongoing work. cg-pull will update
    your .git directory with the history you need to construct your diff,
    without merging that history into your tree, potentially breaking your
    changes."

But I don't know how to cg-diff after the cg-pull? Well as I was writing this it dawned on 
me that if I did a cg-pull I should try:

    cg-diff -r origin

by golly it worked.

So it appears a "cg-diff" with no parameters will show me the changes between my working 
tree and the "HEAD of my repository" and appears to be the same as cg-diff -r HEAD. 
("working tree" appears to mean the contents of what I "see" and therefore includes my 
uncommitted changes and "Repository" refers to contents under .git. Is that correct?)

A "cg-diff -r origin" gives me the differences between my "working tree" and my "origin's" 
current state (as defined by previous "updates" plus any unmerged pull's and there could 
be several pulls without merges).

Is the above correct?

Another area of confusion for me is what are revisions I think I understand what "origin" 
and "HEAD" are but how would I reference others? For instance how to cg-diff between the 
HEAD and the revision before HEAD (or the one 3 days ago or ...)? Can "tags" be used as 
"revisions" (i.e. as "-r tag-xxx").

Actually looking in the repository I see that "origin" appears to be a "branch" not a 
revision, what is the relationship between a branch, tag and revision's? I have some 
experience with subversion and in subversion they are actually all the same, simply the 
state of a "sub-tree" within the repository at a particular "time". That time is defined 
by the repositories current revison number which is incremented after each succesful 
commit to the repository.

Cheers,

Wink


-- 
No virus found in this outgoing message.
Checked by AVG Anti-Virus.
Version: 7.0.308 / Virus Database: 266.11.10 - Release Date: 5/13/2005


^ permalink raw reply

* Re: [PATCH] Resurrect diff-tree-helper -R
From: Junio C Hamano @ 2005-05-15  6:25 UTC (permalink / raw)
  To: Petr Baudis; +Cc: Linus Torvalds, git
In-Reply-To: <20050514233538.GY3905@pasky.ji.cz>

>>>>> "PB" == Petr Baudis <pasky@ucw.cz> writes:

>> Wait a minute.  Aren't we scanning starting from the first
>> '---\n'?  Why does what's in commit message matter?

PB> Ok, that changes the whole situation. I'll take your patches as they are
PB> now in that case. :-)

Shooooooooot.  Seriously.

I already am beginning to like "\n@. " very much; it is much
less distracting then the "# mode: " thing, especially with the
help from additional newline.

Could I have the following applied, pretty please?

------------
Tweak diff output a bit further to make a bit less distracting.

This adds a blank line before start of diffs for each file, and
also changes "# mode: " header to "@. ".  One justification is
that it tells more than just mode, and "@. " is visually a lot
less distracting.

Signed-off-by: Junio C Hamano <junkio@cox.net>
---

--- a/diff.c
+++ b/diff.c
@@ -83,7 +83,7 @@ static void builtin_diff(const char *nam
 			 struct diff_tempfile *temp)
 {
 	int i, next_at;
-	const char *git_prefix = "# mode: ";
+	const char *git_prefix = "\n@. ";
 	const char *diff_cmd = "diff -L'%s%s' -L'%s%s'";
 	const char *diff_arg  = "'%s' '%s'||:"; /* "||:" is to return 0 */
 	const char *input_name_sq[2];
@@ -128,15 +128,17 @@ static void builtin_diff(const char *nam
 	else if (!path1[1][0])
 		printf("%s%s . %s\n", git_prefix, temp[0].mode, name);
 	else {
-		if (strcmp(temp[0].mode, temp[1].mode))
+		if (strcmp(temp[0].mode, temp[1].mode)) {
 			printf("%s%s %s %s\n", git_prefix,
 			       temp[0].mode, temp[1].mode, name);
-
-		if (strncmp(temp[0].mode, temp[1].mode, 3))
-			/* we do not run diff between different kind
-			 * of objects.
-			 */
-			exit(0);
+			if (strncmp(temp[0].mode, temp[1].mode, 3))
+				/* we do not run diff between different kind
+				 * of objects.
+				 */
+				exit(0);
+		}
+		else
+			putchar('\n');
 	}
 	fflush(NULL);
 	execlp("/bin/sh","sh", "-c", cmd, NULL);



^ permalink raw reply

* Re: Mercurial 0.4e vs git network pull
From: Ingo Molnar @ 2005-05-15  6:22 UTC (permalink / raw)
  To: Petr Baudis; +Cc: Matt Mackall, linux-kernel, git, mercurial, Linus Torvalds
In-Reply-To: <20050512182340.GA324@pasky.ji.cz>


* Petr Baudis <pasky@ucw.cz> wrote:

> > Mercurial is also much smarter than rsync at determining what
> > outstanding changesets exist. Here's an empty pull as a demonstration:
> > 
> >  $ time hg merge hg://selenic.com/linux-hg/
> >  retrieving changegroup
> > 
> >  real    0m0.363s
> >  user    0m0.083s
> >  sys     0m0.007s
> > 
> > That's a single http request and a one line response.
> 
> So, what about comparing it with something comparable, say git pull 
> over HTTP? :-)

Matt, did you get around to do such a comparison?

	Ingo

^ permalink raw reply

* Re: [RFD] Ignore rules
From: Junio C Hamano @ 2005-05-15  6:05 UTC (permalink / raw)
  To: jon; +Cc: Petr Baudis, David Greaves, torvalds, GIT Mailing Lists
In-Reply-To: <2cfc4032050514181127c02e43@mail.gmail.com>

>>>>> "JS" == Jon Seymour <jon.seymour@gmail.com> writes:

JS> Is there value in:

JS> a. pushing the ignore logic into the core git tools such as git-ls-files

When there is an agreed upon Porcelain layer ignore logic,
git-ls-files --others --exclude-from=... should be changed so
that it uses the same file format and same semantics, and
probably use the default ignore file without being explicitly
told.  Otherwise things would get quite confusing, so yes, I see
value in there.

I do not however think this should apply to things like
"git-update-cache --add"; because even though user may say
"git-update-cache --add *" and wish it to ignore things on the
ignore list, that is not how shell parameter expansion works.

I would like to see a git-path-helper command that can act as
filter between "find -print0" and "xargs -0" like this:

    find * -print0 |
    git-path-helper -z --ignore-file=.git/info/ignore |
    xargs -r -0 git-update-cache --add --

I envision that we should not even need --ignore-file parameter,
once we have "an agreed upon Porcelain layer ignore logic".  It
should read the "agreed upon" location, somewhere under the
$GIT_DIR and perform the "agreed upon" filtering logic.

I further envision that this would work from anywhere in the
work tree, not only from the directory that corresponds to the
top of the tree structure GIT_INDEX_FILE describes.  For
example, in linux-2.6 git tree, you _ought_ to be able to say
something like this:

    cd fs
    find ext? ../include/linux -type f -print0 |
    git-path-helper -z |
    xargs -r -0 git-update-cache --add --

The git-path-helper command could internally run getpwd() and
find out the top directory (in this case, the parent directory
of our current working directory "fs"), then canonicalize the
incoming filenames (either relative to getpwd() or the full
filesystem path) to paths relative to the top directory, apply
the ignore filter and send the surviving paths downstream.
Anything downstream driven with xargs -0 would get relative
paths suitable for core GIT consumption.

JS> b. including the current ignore .* rule as a default ignore rule that
JS> can be overridden by a .gitignore file

Knowing the number of places that assume .* are irrelevant, I
would not be looking forward to doing that myself, but that
behaviour would be ideal.



^ permalink raw reply

* Re: [PATCH 0/4] Pulling refs files
From: Junio C Hamano @ 2005-05-15  5:33 UTC (permalink / raw)
  To: Daniel Barkalow; +Cc: Petr Baudis, git, Linus Torvalds
In-Reply-To: <Pine.LNX.4.21.0505130245260.30848-100000@iabervon.org>

I am having a bit hard time understanding how the end user uses
what you are trying to give them.  Is the basic idea to let them
say "I want to get Pasky's $GIT_DIR/refs/heads/master and store
it in my $GIT_DIR/refs/heads/git-pb, and then I want to start
the pull starting from the commit recorded in that ref"?

Assuming that is what you are doing, I do not have much
objection to it.  I however think introducing REFS_ENVIRONMENT
is going overboard.

My understanding of the definition of GIT_DIR is "the directory
traditionally known as $(pwd)/.git/ where various things hang
underneath".  We have GIT_OBJECT_DIRECTORY configurable to be
set to something other than $GIT_DIR/objects because people may
want to use shared object pools.  We have GIT_INDEX_FILE
configurable to be set to something other than $GIT_DIR/index
because being able to have it on tmp filesystem for some
application (like "merge my head and his head without using what
I have in my work dir which is a bit ahead of my head already")
helps performance; also some Porcelain operations benefit from
being able to switch between multiple cache files.  I cannot
think of a similar argument with an example use pattern that
justifies REFS_ENVIRONMENT being set to anything other than
$GIT_DIR/refs/.


^ permalink raw reply

* [PATCH] Add --author and --committer match to rev-list and rev-tree.
From: Junio C Hamano @ 2005-05-15  4:57 UTC (permalink / raw)
  To: pasky, torvalds; +Cc: git
In-Reply-To: <7vpsvu2ksd.fsf@assigned-by-dhcp.cox.net>

Zack Brown wondered if handling author match at core GIT level
would make cg-log -u go faster (JIT also can use this in jit-log
--author).  Later Peter Baudis wanted to have --committer match
similar to it.

This version is improved from the one I posted to GIT list
earlier in that:

 (1) I bit the bullet and added author and committer names to
     the commit object, so there is no double unpacking anymore.
     The strings are shared across multiple commits so consider
     them intern'ed and do not free them.

 (2) Determination of if author and committer names are
     "interesting" is done only once per name, not per commit.
     This version uses simple "substring" logic, but it is
     easily extendable for more interesting match such as
     regexps.

This also fixes documentation of git-rev-list which did not
describe its already existing options.

Signed-off-by: Junio C Hamano <junkio@cox.net>
---

*** The previous round that has not been merged to git-pb should
*** be discarded.  This is a patch against the tip of git-pb as
*** of this writing.

Documentation/git-rev-list.txt    |   19 +++++
Documentation/git-rev-tree.txt    |    8 +-
commit.c                          |  135 +++++++++++++++++++++++++++++++++-----
commit.h                          |   18 ++++-
rev-list.c                        |   18 ++++-
rev-tree.c                        |   27 +++++++
t/t6010-rev-tree-author-commit.sh |   98 +++++++++++++++++++++++++++
t/t6110-rev-list-author-commit.sh |   97 +++++++++++++++++++++++++++
8 files changed, 396 insertions(+), 24 deletions(-)
t/t6010-rev-tree-author-commit.sh (. --> 100755)
t/t6110-rev-list-author-commit.sh (. --> 100755)

--- a/Documentation/git-rev-list.txt
+++ b/Documentation/git-rev-list.txt
@@ -9,7 +9,7 @@
 
 SYNOPSIS
 --------
-'git-rev-list' <commit>
+'git-rev-list' [--author=author] [--committer=committer] [--max-count=count] [--max-age=unixtime] [--min-age=unixtime] <commit>
 
 DESCRIPTION
 -----------
@@ -18,6 +18,23 @@
 useful to produce human-readable log output.
 
 
+OPTIONS
+-------
+--author::
+	Limit the final output to commits written by the author.
+
+--committer::
+	Limit the final output to commits committed by the author.
+
+--max-count::
+	Stop after showing the specified number of commits.
+
+--max-age::
+	Stop before showing the commits older than specified time.
+
+--min-age::
+	Do not show the commits newer than specified time.
+
 Author
 ------
 Written by Linus Torvalds <torvalds@osdl.org>
--- a/Documentation/git-rev-tree.txt
+++ b/Documentation/git-rev-tree.txt
@@ -9,7 +9,7 @@
 
 SYNOPSIS
 --------
-'git-rev-tree' [--edges] [--cache <cache-file>] [^]<commit> [[^]<commit>]
+'git-rev-tree' [--author author] [--committer committer] [--edges] [--cache <cache-file>] [^]<commit> [[^]<commit>]
 
 DESCRIPTION
 -----------
@@ -17,6 +17,12 @@
 
 OPTIONS
 -------
+--author::
+	Limit the final output to commits written by the author.
+
+--committer::
+	Limit the final output to commits committed by the author.
+
 --edges::
 	Show edges (ie places where the marking changes between parent
 	and child)
--- a/commit.c
+++ b/commit.c
@@ -23,22 +23,111 @@
 	return (struct commit *) obj;
 }
 
-static unsigned long parse_commit_date(const char *buf)
-{
-	unsigned long date;
+static struct person_name **person_name;
+static int person_nr;
+static int person_alloc;
+
+static const char *interesting_author = NULL;
+static const char *interesting_committer = NULL;
+
+void commit_author_committer_match_initialize(const char *author,
+					      const char *committer)
+{
+	interesting_author = author;
+	interesting_committer = committer;
+}
+
+static int person_name_pos(const char *name)
+{
+	int first, last;
+
+	first = 0;
+	last = person_nr;
+	while (last > first) {
+		int next = (last + first) >> 1;
+		struct person_name *pn = person_name[next];
+		int cmp = strcmp(name, pn->name);
+		if (!cmp)
+			return next;
+		if (cmp < 0) {
+			last = next;
+			continue;
+		}
+		first = next+1;
+	}
+	return -first-1;
+}
 
-	if (memcmp(buf, "author", 6))
-		return 0;
-	while (*buf++ != '\n')
-		/* nada */;
-	if (memcmp(buf, "committer", 9))
-		return 0;
-	while (*buf++ != '>')
-		/* nada */;
-	date = strtoul(buf, NULL, 10);
-	if (date == ULONG_MAX)
-		date = 0;
-	return date;
+#define INTERESTING_AUTHOR    01
+#define INTERESTING_COMMITTER 02
+
+static struct person_name *person_name_lookup(const char *name)
+{
+	int pos = person_name_pos(name);
+	struct person_name *pn; 
+	if (0 <= pos)
+		return person_name[pos];
+	pos = -pos-1;
+	pn = xmalloc(sizeof(*pn) + strlen(name) + 1);
+	strcpy(pn->name, name);
+	pn->mark = 0;
+
+	/*
+	 * When we decide we want to go fancier, strstr() below
+	 * can be replaced with something like regexp match to
+	 * pick up more than one author or committer.  For now
+	 * let's try simple substring find and see what happens.
+	 * Note that not specifying anybody means we are interested
+	 * in everybody.
+	 */
+	if (!interesting_author || strstr(name, interesting_author))
+		pn->mark |= INTERESTING_AUTHOR;
+	if (!interesting_committer || strstr(name, interesting_committer))
+		pn->mark |= INTERESTING_COMMITTER;
+
+	if (person_nr == person_alloc) {
+		person_alloc = alloc_nr(person_alloc);
+		person_name = xrealloc(person_name, person_alloc *
+				       sizeof(struct person_name *));
+	}
+	person_nr++;
+	if (pos < person_nr)
+		memmove(person_name + pos + 1, person_name + pos,
+			(person_nr - pos - 1) * sizeof(pn));
+	person_name[pos] = pn;
+	return pn;
+}
+
+static void *parse_commit_nametime(char *ptr, const char *ep,
+				   const char *field,
+				   unsigned long *date,
+				   struct person_name **name)
+{
+	unsigned long d;
+	char *cp;
+	int fldlen = strlen(field);
+	if (ptr == NULL || memcmp(ptr, field, fldlen) || ptr[fldlen] != ' ') {
+		*date = 0;
+		*name = NULL;
+		return NULL; /* malformed commit */
+	}
+	for (cp = ptr + fldlen + 1; cp < ep && *cp != '>'; cp++)
+		; /* skip */
+	if (*cp != '>' || *++cp != ' ') {
+		*date = 0;
+		*name = NULL;
+		return NULL; /* malformed commit */
+	}
+	*cp = 0;
+	*name = person_name_lookup(ptr + fldlen + 1);
+	*cp++ = ' ';
+	d = strtoul(cp, NULL, 10);
+	if (d == ULONG_MAX)
+		d = 0;
+	*date = d;
+	while (cp < ep && *cp++ != '\n')
+		; /* skip */
+	return cp;
 }
 
 int parse_commit_buffer(struct commit *item, void *buffer, unsigned long size)
@@ -63,7 +152,13 @@
 		}
 		bufptr += 48;
 	}
-	item->date = parse_commit_date(bufptr);
+	
+	bufptr = parse_commit_nametime(bufptr, (char *)buffer + size,
+				       "author", &item->author_date,
+				       &item->author);
+	parse_commit_nametime(bufptr, (char *)buffer + size,
+			      "committer", &item->date,
+			      &item->committer);
 	return 0;
 }
 
@@ -152,3 +247,11 @@
 	}
 	return ret;
 }
+
+int commit_author_committer_match(struct commit *item)
+{
+	return ( ((item->author != NULL) &&
+		  (item->author->mark & INTERESTING_AUTHOR)) &&
+		 ((item->committer != NULL) &&
+		  (item->committer->mark & INTERESTING_COMMITTER)) );
+}
--- a/commit.h
+++ b/commit.h
@@ -11,8 +11,9 @@
 
 struct commit {
 	struct object object;
-	unsigned long date;
+	unsigned long author_date, date;
 	struct commit_list *parents;
+	struct person_name *author, *committer; 
 	struct tree *tree;
 };
 
@@ -36,4 +37,19 @@
 struct commit *pop_most_recent_commit(struct commit_list **list, 
 				      unsigned int mark);
 
+struct person_name {
+	char mark;
+	char name[0];
+};
+
+/* This function must be called before fetching any commit object
+ * if commit-author-committer-match function is to be used to filter
+ * commits for output.  Passing NULL is permitted, which makes all
+ * authors (or committers) "interesting".
+ */
+void commit_author_committer_match_initialize(const char *, const char *);
+
+/* Returns true only if author and committer are "interesting". */
+int commit_author_committer_match(struct commit *);
+
 #endif /* COMMIT_H */
--- a/rev-list.c
+++ b/rev-list.c
@@ -11,6 +11,8 @@
 	unsigned long max_age = -1;
 	unsigned long min_age = -1;
 	int max_count = -1;
+	const char *author = NULL;
+	const char *committer = NULL;
 
 	for (i = 1 ; i < argc; i++) {
 		char *arg = argv[i];
@@ -21,6 +23,10 @@
 			max_age = atoi(arg + 10);
 		} else if (!strncmp(arg, "--min-age=", 10)) {
 			min_age = atoi(arg + 10);
+		} else if (!strncmp(arg, "--author=", 9)) {
+			author = arg + 9;
+		} else if (!strncmp(arg, "--committer=", 12)) {
+			committer = arg + 12;
 		} else {
 			commit_arg = arg;
 		}
@@ -28,9 +34,13 @@
 
 	if (!commit_arg || get_sha1(commit_arg, sha1))
 		usage("usage: rev-list [OPTION] commit-id\n"
-		      "  --max-count=nr\n"
-		      "  --max-age=epoch\n"
-		      "  --min-age=epoch\n");
+		      "  --author=author\n"
+		      "  --committer=committer\n"
+		      "  --max-count=number\n"
+		      "  --max-age=unixtime\n"
+		      "  --min-age=unixtime\n");
+
+	commit_author_committer_match_initialize(author, committer);
 
 	commit = lookup_commit(sha1);
 	if (!commit || parse_commit(commit) < 0)
@@ -44,6 +54,8 @@
 			continue;
 		if (max_age != -1 && (commit->date < max_age))
 			break;
+		if (!commit_author_committer_match(commit))
+			continue;
 		if (max_count != -1 && !max_count--)
 			break;
 		printf("%s\n", sha1_to_hex(commit->object.sha1));
--- a/rev-tree.c
+++ b/rev-tree.c
@@ -64,7 +64,7 @@
 }
 
 /*
- * Usage: rev-tree [--edges] [--cache <cache-file>] <commit-id> [<commit-id2>]
+ * Usage: rev-tree [--edges] [--author <author>] [--cache <cache-file>] <commit-id> [<commit-id2>]
  *
  * The cache-file can be quite important for big trees. This is an
  * expensive operation if you have to walk the whole chain of
@@ -75,6 +75,9 @@
 	int i;
 	int nr = 0;
 	unsigned char sha1[MAX_COMMITS][20];
+	const char *author = NULL; 
+	const char *committer = NULL;
+	int initialized_author_commiter = 0;
 
 	/*
 	 * First - pick up all the revisions we can (both from
@@ -83,6 +86,16 @@
 	for (i = 1; i < argc ; i++) {
 		char *arg = argv[i];
 
+		if (!strcmp(arg, "--author")) {
+			author = argv[++i];
+			continue;
+		}
+
+		if (!strcmp(arg, "--committer")) {
+			committer = argv[++i];
+			continue;
+		}
+
 		if (!strcmp(arg, "--cache")) {
 			read_cache_file(argv[++i]);
 			continue;
@@ -98,7 +111,14 @@
 			basemask |= 1<<nr;
 		}
 		if (nr >= MAX_COMMITS || get_sha1(arg, sha1[nr]))
-			usage("rev-tree [--edges] [--cache <cache-file>] <commit-id> [<commit-id>]");
+			usage("rev-tree [--edges] [--author <author>] [--committer <committer>] [--cache <cache-file>] <commit-id> [<commit-id>]");
+
+		if (!initialized_author_commiter) {
+			commit_author_committer_match_initialize(author,
+								 committer);
+			initialized_author_commiter = 1;
+		}
+
 		process_commit(sha1[nr]);
 		nr++;
 	}
@@ -125,6 +145,9 @@
 		if (!interesting(commit))
 			continue;
 
+		if (!commit_author_committer_match(commit))
+			continue;
+
 		printf("%lu %s:%d", commit->date, sha1_to_hex(obj->sha1), 
 		       obj->flags);
 		p = commit->parents;
--- a/t/t6010-rev-tree-author-commit.sh
+++ b/t/t6010-rev-tree-author-commit.sh
@@ -0,0 +1,98 @@
+#!/bin/sh
+#
+# Copyright (c) 2005 Junio C Hamano
+#
+
+test_description='git-rev-tree --author and --committer flags.
+'
+
+. ./test-lib.sh
+
+export_them () {
+export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL
+}
+
+set_author_zero () {
+    GIT_AUTHOR_NAME="A U Thor" &&
+    GIT_AUTHOR_EMAIL="<author@example.xz>"
+}
+set_author_one () {
+    GIT_AUTHOR_NAME="R O Htua" &&
+    GIT_AUTHOR_EMAIL="<rohtua@example.xz>"
+}
+set_committer_zero () {
+    GIT_COMMITTER_NAME="C O Mmitter" &&
+    GIT_COMMITTER_EMAIL="<committer@example.xz>"
+}
+set_committer_one () {
+    GIT_COMMITTER_NAME="R E Ttimmoc" &&
+    GIT_COMMITTER_EMAIL="<rettimmoc@example.xz>"
+}
+
+# read rev-tree output, and find the author|committer of commit object
+pick_actor () {
+    sed -e 's/^[^ ]* //;s/:.*//' |
+    xargs -r -n1 git-cat-file commit |
+    sed -ne 's/^\('"$1"'\) \([^>]*>\).*/\2/p'
+}
+
+test_expect_success \
+    'preparation' '
+echo frotz >path0 &&
+git-update-cache --add path0 &&
+tree0=$(git-write-tree) &&
+
+set_author_zero &&
+set_committer_zero &&
+export_them &&
+commit0=$(echo frotz | git-commit-tree $tree0) &&
+
+set_author_zero &&
+set_committer_one &&
+export_them &&
+commit1=$(echo frotz | git-commit-tree $tree0 -p $commit0) &&
+
+set_author_one &&
+set_committer_zero &&
+export_them &&
+commit2=$(echo frotz | git-commit-tree $tree0 -p $commit1) &&
+
+set_author_one &&
+set_committer_one &&
+export_them &&
+commit3=$(echo frotz | git-commit-tree $tree0 -p $commit2)'
+
+test_expect_success \
+    'without restriction git-rev-tree should report all four commits.' \
+    'test $(git-rev-tree $commit3 | wc -l) == 4'
+
+test_expect_success \
+    'limiting to A U Thor (two commits)' '
+    case "$(git-rev-tree --author "A U Thor" $commit3 |
+          pick_actor "author" | sort -u)" in
+    "A U Thor <author@example.xz>") : ;;
+    *) (exit 1) ;;
+    esac'
+
+test_expect_success \
+    'limiting to R E Ttimmoc (two commits)' '
+    case "$(git-rev-tree --committer "R E Ttimmoc" $commit3 |
+          pick_actor "committer" | sort -u)" in
+    "R E Ttimmoc <rettimmoc@example.xz>") : ;;
+    *) (exit 1) ;;
+    esac'
+
+LF='
+'
+
+test_expect_success \
+    'limiting to A U Thor and C O Mmitter (one commit)' '
+    case "$(git-rev-tree --author "A U Thor" --committer "C O Mmitter" \
+            $commit3 | pick_actor "committer\\|author" | sort -u)" in
+    "A U Thor <author@example.xz>${LF}C O Mmitter <committer@example.xz>")
+        : ;;
+    *) (exit 1) ;;
+    esac
+'
+
+test_done
--- a/t/t6110-rev-list-author-commit.sh
+++ b/t/t6110-rev-list-author-commit.sh
@@ -0,0 +1,97 @@
+#!/bin/sh
+#
+# Copyright (c) 2005 Junio C Hamano
+#
+
+test_description='git-rev-list --author and --committer flags.
+'
+
+. ./test-lib.sh
+
+export_them () {
+export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL
+}
+
+set_author_zero () {
+    GIT_AUTHOR_NAME="A U Thor" &&
+    GIT_AUTHOR_EMAIL="<author@example.xz>"
+}
+set_author_one () {
+    GIT_AUTHOR_NAME="R O Htua" &&
+    GIT_AUTHOR_EMAIL="<rohtua@example.xz>"
+}
+set_committer_zero () {
+    GIT_COMMITTER_NAME="C O Mmitter" &&
+    GIT_COMMITTER_EMAIL="<committer@example.xz>"
+}
+set_committer_one () {
+    GIT_COMMITTER_NAME="R E Ttimmoc" &&
+    GIT_COMMITTER_EMAIL="<rettimmoc@example.xz>"
+}
+
+# read rev-list output, and find the author|committer of commit object
+pick_actor () {
+    xargs -r -n1 git-cat-file commit |
+    sed -ne 's/^\('"$1"'\) \([^>]*>\).*/\2/p'
+}
+
+test_expect_success \
+    'preparation' '
+echo frotz >path0 &&
+git-update-cache --add path0 &&
+tree0=$(git-write-tree) &&
+
+set_author_zero &&
+set_committer_zero &&
+export_them &&
+commit0=$(echo frotz | git-commit-tree $tree0) &&
+
+set_author_zero &&
+set_committer_one &&
+export_them &&
+commit1=$(echo frotz | git-commit-tree $tree0 -p $commit0) &&
+
+set_author_one &&
+set_committer_zero &&
+export_them &&
+commit2=$(echo frotz | git-commit-tree $tree0 -p $commit1) &&
+
+set_author_one &&
+set_committer_one &&
+export_them &&
+commit3=$(echo frotz | git-commit-tree $tree0 -p $commit2)'
+
+test_expect_success \
+    'without restriction git-rev-tree should report all four commits.' \
+    'test $(git-rev-list $commit3 | wc -l) == 4'
+
+test_expect_success \
+    'limiting to A U Thor (two commits)' '
+    case "$(git-rev-list --author="A U Thor" $commit3 |
+          pick_actor "author" | sort -u)" in
+    "A U Thor <author@example.xz>") : ;;
+    *) (exit 1) ;;
+    esac'
+
+test_expect_success \
+    'limiting to R E Ttimmoc (two commits)' '
+    case "$(git-rev-list --committer="R E Ttimmoc" $commit3 |
+          pick_actor "committer" | sort -u)" in
+    "R E Ttimmoc <rettimmoc@example.xz>") : ;;
+    *) (exit 1) ;;
+    esac'
+
+LF='
+'
+
+test_expect_success \
+    'limiting to A U Thor and C O Mmitter (one commit)' '
+    case "$(git-rev-list --author="A U Thor" --committer="C O Mmitter" \
+            $commit3 | pick_actor "committer\\|author" | sort -u)" in
+    "A U Thor <author@example.xz>${LF}C O Mmitter <committer@example.xz>")
+        : ;;
+    *) (exit 1) ;;
+    esac
+'
+
+test_done
------------------------------------------------


^ permalink raw reply

* Re: README rewrite
From: Zack Brown @ 2005-05-15  4:49 UTC (permalink / raw)
  To: Petr Baudis; +Cc: git
In-Reply-To: <20050515044244.GA7391@tumblerings.org>

Here's an updated patch with fixes, apply instead of the one I just sent:

Signed-off-by: Zack Brown <zbrown@tumblerings.org>


README: needs update
Index: README
===================================================================
--- 4ef3de6ae44888d83e8c00326ddcc9f40cbd12e2/README  (mode:100644)
+++ uncommitted/README  (mode:100644)
@@ -1,164 +1,656 @@
-	GIT - the stupid content tracker
+                Cogito
 
-"git" can mean anything, depending on your mood.
+Cogito is a version control system layered on top of the git
+content-tracking filesystem. This document first describes some quick ways
+to get started using Cogito, then goes over each available command one by
+one.
 
- - random three-letter combination that is pronounceable, and not
-   actually used by any common UNIX command.  The fact that it is a
-   mispronunciation of "get" may or may not be relevant.
- - stupid. contemptible and despicable. simple. Take your pick from the
-   dictionary of slang.
- - "global information tracker": you're in a good mood, and it actually
-   works for you. Angels sing, and a light suddenly fills the room. 
- - "goddamn idiotic truckload of sh*t": when it breaks
+            Quickstart
 
-The GIT itself is merely an extremely fast and flexible filesystem-based
-database designed to store directory trees with regard to their history.
-The top layer is a SCM-like tool Cogito which enables human beings to work
-with the database in a manner to a degree similar to other SCM tools (like
-CVS, BitKeeper or Monotone).
+        Downloading Cogito From Scratch
+
+Cogito can be obtained as a tarball from
+
+http://www.kernel.org/pub/software/scm/cogito/
+
+Download and unpack the latest version, build with make, put the executables
+somewhere in your $PATH (or add your Cogito directory itself to your $PATH),
+and you're ready to go!
+
+The following tools are required by Cogito:
+
+bash
+basic shell environment (sed, grep, textutils, ...)
+diff
+patch
+RCS (the merge program from this package)
+mktemp 1.5+ (Mandrake users beware!)
+libssl
+rsync
+libcurl
+
+        Starting A Fresh git Repository
+
+If you want to start your own project using Cogito, there are two basic ways
+to do this. You may start a fresh repository with no files in it, or you may
+take an existing directory tree and turn it into a git repository.
+
+    Starting An Empty Repository
+
+To create a new repository with no files in it, cd into an empty directory,
+and give the following command:
+
+$ cg-init
+
+Your editor will start up, and you will be asked to type in an initial
+commit description. Type something cute, and exit your editor.
+
+That's it! You're now in your own git repository. Notice there is now a git
+.directory. Go into it and look around, but don't change anything in
+there. That's what Cogito commands are for.
+
+    Turning An Existing Directory Into A Repository
+
+If you have a directory full of files, you can easily turn this into a
+git repository. In fact, it is virtually the same as starting an empty
+repository. Just cd into the directory you want converted into a git
+repository, and give the following command:
+
+$ cg-init
+
+Your editor starts up, you type in an initial commit message, exit your
+editor, and you're good to go. All of the files and directories within that
+directory are now part of a git archive.
+
+        Accessing Someone Else's git Repository
+
+    Creating The Repository
+
+If you want to get started tracking an outside git repository, you first
+must have Cogito's executables on your $PATH. Next, you need the URL (or
+local directory path) of the repository you want to track. You can't just
+use the URL of a tarball, like the one given above for the Cogito source.
+The URL must point specifically to a .git directory somewhere. For instance,
+the URL for Cogito's self-hosting repository is
+
+rsync://rsync.kernel.org/pub/scm/cogito/cogito.git
+
+Notice that the final filename, 'cogito.git', is not called '.git'. That is
+fine. It's still a .git directory.
+
+To clone the repository to your local filesystem, use the cg-clone command.
+cg-clone can be told to create a new directory for your repository, or to
+drop the repository into the current directory.
+
+To have a new directory created, just include the directory in the command,
+as follows:
+
+$ cg-clone rsync://rsync.kernel.org/pub/scm/cogito/cogito.git cogitodir
+
+You will see a whole bunch of output, and when it is over, there will be a
+new directory called 'cogitodir' (or whatever name you chose) in the current
+directory. cd into it. Because we used the Cogito URL, you will see the
+Cogito source tree, with its own .git directory keeping track of everything.
+
+If, instead, you want to clone the repository to the current directory,
+first make sure you are in an empty directory. Then give the following
+command:
+
+$ cg-clone -s rsync://rsync.kernel.org/pub/scm/cogito/cogito.git
+
+When you get your prompt back, do an ls to see the source tree and .git
+directory.
+
+    Tracking The Repository
+
+Of course, once you have cloned a repository, you don't just want to leave
+it at that. The upstream sources are constantly being updated, and you want
+to follow these updates. To do this, cd into the repository directory (not
+the .git directory, but the directory that contains the .git directory), and
+give the following command:
+
+$ cg-update
+
+You don't use a URL anymore. Cogito knows which tree you're tracking,
+because this information is stored in the .git directory. The above command
+will track the 'origin' branch, which is the primary branch of development.
+But cg-update can also be used to track specific branches. See below for
+more discussion of branches, and how to track them.
+
+When you give the above cg-update command, this performed two actions.
+First, it pulled all new changes from the upstream repository into your
+local repository. At that point, the changes exist in your local repository
+as part of the project's history. The changes themselves are not actually
+visible in the files you see, but reside in the .git directory's awareness.
+The second thing cg-update does is to merge these changes into the files you
+see and work with. The end result is that, when the cg-update has finished,
+you will see all the upstream changes reflected in your local files, and the
+.git directory will be aware of the history of those changes as well.
+
+It may be that you want to be aware of the history of the upstream work, but
+you don't yet want those changes merged with your own local files. To do
+this, give the following command:
+
+$ cg-pull
+
+This does the first part of cg-update's behavior, but skips the second part.
+Now your local files have not been changed, but your .git directory has been
+updated with the history of all the changes that have occurred in the
+upstream sources.
+
+Using cg-pull is useful for a variety of purposes, for instance if you want
+to construct a diff against the latest version of the upstream sources, but
+don't want those changes to disturb your ongoing work. cg-pull will update
+your .git directory with the history you need to construct your diff,
+without merging that history into your tree, potentially breaking your
+changes.
+
+Typically, if you are not making changes to a repository yourself, but just
+want the latest version of a given project for your own use, you would use
+cg-update. cg-pull is strictly for development work.
+
+Once you've done a cg-pull, you may decide you want to merge after all. In
+this case a cg-update command will do the trick, however you will also
+update your local files with any further upstream changes that have occurred
+since your cg-pull.
+
+        Getting Help
+
+Cogito commands come with their own helpful documentation. To get help on
+cg-update, for example, give this command:
+
+$ cg-pull --help
+
+or, for the same information, try this:
+
+$ cg-help cg-pull
+
+            Command Reference
+
+        Caveats
+
+    What are those cg-Xes?
+
+There are three executables, cg-Xdiffdo, cg-Xlib, and cg-Xmergefile, that
+are not meant to be used from the command line. They provide a library of
+generic functions used by many of the real cg-* commands. You can safely
+ignore them, unless you want to contribute to Cogito development.
+
+    What about file renames?
+
+File renaming (and tracking the history of a file from name to name) is
+being worked on. git provides a wonderful, elegant way to track content as
+it moves from file to file, and renames should be a special case of this.
+
+    Can I give Cogito commands from a subdirectory?
+
+Cogito currently requires that commands be given from the base directory,
+the one containing the .git directory. Patches have been submitted to
+implement the ability to give Cogito commands from subdirectories within the
+repository, but Linus prefers the current behavior.
+
+        cg-add
+
+This command is used to add files to the git repository. It takes a list of
+files on the command line, and schedules them for addition. To actually add
+them, however, you must subsequently give a cg-commit command.
+
+$ cg-add file1 file2 dir1/file3 dir1/file4 dir2/dir3/file5
+
+The above command schedules file1, file2, file3, file4, and file5 to be
+added to the repository at the next cg-commit.
+
+Notice that you never need to add directories to a repository, in fact
+Cogito won't let you. Directories are added automatically when you add the
+files that are inside them. So you can do something like this:
+
+$ mkdir testdir
+$ echo "testtext" > testdir/testfile
+$ cg-add testdir/testfile
+$ cg-commit
+
+and the testdir directory and testfile file will both be added to the
+repository. If you then do a cg-seek to look at an earlier version of the
+repository, both the file and the directory will be gone.
+
+        cg-admin-lsobj
+
+STUB
+
+        cg-admin-uncommit
+
+STUB
+
+        cg-branch-add
+
+STUB
+
+        cg-branch-ls
+
+STUB
+
+        cg-cancel
+
+This undoes all the changes you have made but not committed to your
+repository. Changes you have already committed are kept. All others are
+reverted to their previous form.
+
+If you have given any cg-add commands, these are also undone in the sense
+that the files and directories will no longer be added on a cg-commit. The
+files and directories themselves are not deleted by a cg-cancel.
+
+        cg-clone
+
+This checks out a remote repository into a local filesystem. It is only used
+for the initial creation of the local repository. Subsequent updates to
+track the upstream sources are done with cg-update or cg-pull.
+
+In its simplest form, cg-clone takes a URL or directory path to a remote
+repository:
+
+$ cg-clone rsync://rsync.kernel.org/pub/scm/cogito/cogito.git
 
+The above command interprets the URL and takes the base directory (in this
+case 'cogito') as the target for the new repository. If the directory
+already exists within the current directory, cg-clone exits with an error
+message. Otherwise this directory is created within the current directory.
+cg-clone then clones the upstream repository into that directory.
 
+It's also possible to specify the target directory by hand on the command
+line, as follows:
 
-	Cogito
-	~~~~~~
+$ cg-clone rsync://rsync.kernel.org/pub/scm/cogito/cogito.git targetdir
 
-This currently simply describes what should you do when you get a tarball
-of Cogito and start to use it and hack upon it. It can give you some guide,
-but the documentation should be certainly consolidated and rewritten.
+If targetdir already exists, cg-clone will exit again with an error message.
+Otherwise, targetdir is created, and the upstream repository is cloned into
+it.
 
-Build it by make, make sure the scripts are in $PATH.
+If you want to clone the upstream sources into the current directory, use
+the -s option:
 
-If, after unpacking the tarball, you do not have the .git subdirectory in the
-tarball root, you
+$ cg-clone -s rsync://rsync.kernel.org/pub/scm/cogito/cogito.git
 
-	cg-clone -s rsync://rsync.kernel.org/pub/scm/cogito/cogito.git
+This will not create a new directory anywhere, but will just create the
+repository directly into the current directory. Any files or directories
+already in the current directory will not be overwritten, and files of the
+same name will retain their old contents. Typically, you never want to use
+the -s option in a directory with existing files or subdirectories.
 
-in that directory, and
+        cg-commit
 
-	cg-branch-add pasky rsync://rsync.kernel.org/pub/scm/cogito/cogito.git
+This command is used after you have edited files in a repository, and now
+want to include your changes in the project history. After a cg-commit, your
+changes will have a changelog entry, including your identity, the date of
+the change, and other information.
 
-(there is already the same branch called "origin" created by cg-clone, however
-we expect the branch name to be "pasky" for the result of the tutorial;
-alternatively, just use "origin" everywhere instead of "pasky").
+Typically you do not need to give any command line options to cg-commit, but
+just use it in its simplest form:
 
-If you already have the .git subdirectory, update it to the latest version by
+$ cg-commit
 
-	cg-update pasky
+This will fire up your editor and ask for a changelog entry. If you leave
+this text blank, a changelog entry will still be created, but with no
+explanatory text. When you exit your editor, your changed files and
+changelog entry are included in the history of the repository, and are
+subject to full version control.
 
-(and repeat that after some time to get the future updates - but see below).
-Then build it again, doing
+There are several ways to avoid dealing with an editor at commit time.
+cg-commit accepts changelog entries from standard input:
 
-	make
+$ echo "my first changelog entry" | cg-commit
 
-and...  well, that's it. Play around with it a bit. ;-)
+You can also specify your changelog entry with the -m option to cg-commit:
 
-You can get my latest changes by doing:
+$ cg-commit -m"my first changelog entry"
 
-	cg-update pasky
+If a changelog entry is sent via standard input, and another one is included
+in a -m option, the entry from standard input is appended with no blank line
+after the entry from the -m option.
 
-If you did some local commits in the meantime, Cogito will attempt to merge
-them with the pasky branch. You then need to check that the merging went
-correctly and without conflicts, possibly do merge-related fixes, and then
-record the merge with cg-commit (if the merge was clean, Cogito will commit
-automatically).
+Multiple -m options can also be given, and they will each be appended, with
+a blank line between, after the one before in the changelog entry.
 
-Sometimes, you will just want to bring the latest stuff from my branch, but not
-merge it (e.g. you might want only to diff against it). Do that by
+A -e option also exists, to force an editor to come up for a commit message,
+even if -m options are present, or if there is data coming from standard
+input. In this case, all input from standard input or -m options is appended
+with a blank line after the text typed into the editor.
 
-	cg-pull pasky
+A -E option also exists and behaves identically to -e, except it will force
+the commit even if the default commit message is not changed.
 
-If there are any changes, two IDs will be printed (I mean the line saying
-"Tree change"). Pass those as parameters to cg-diff and you will get a diff
-describing changes from the last time you pulled. You can also
+A -C option also exists, but it is for internal purposes. You can safely
+ignore it.
 
-	cg-diff -r pasky:HEAD
+There are several environment variables you may use to control the
+authentication information included with the changelog entry. Typically,
+Cogito uses getpwuid(getuid()) to identify the user. This can be overridden
+with these variables:
 
-which will show changes between my and your branch.
+GIT_AUTHOR_NAME       Author's name
+GIT_AUTHOR_EMAIL      Author's e-mail address
+GIT_AUTHOR_DATE       Date, perhaps from a patch e-mail
+GIT_COMMITTER_NAME    Committer's name
+GIT_COMMITTER_EMAIL   Committer's e-mail address
 
-Note that you can also access the Linus' official branch, just by specifying
-'linus' instead of 'pasky'. You can of course add more branches by:
+In the above variables - and in the changelog entries - the author is the
+person who actually wrote a given patch, and the committer is the person who
+actually gave the command to include this patch in the repository. If you
+are just working on your own repository, or if you commit your own patches,
+then the author and committer are both you.
 
-	cg-branch-add name rsyncurl
+        cg-diff
 
-(the rsyncurl can have a fragment part identifying a branch inside of the
-repository accessible over rsync).  When you do some local changes, you can do
+This compares two trees and outputs a diff, suitable for feeding into the
+patch program. If there is no difference between the trees, cg-diff just
+outputs "ok".
 
-	cg-diff
+With no arguments, it compares the state of your working tree, including all
+your uncommitted changes, with the state of the tree at the last commit. The
+result in this case is a diff showing only the changes you have not yet
+committed. To do this, give the following command:
 
-to display them. "ok" means it's identical, while hash printed means that there
-is some difference. This is a little troublesome so far, since it doesn't like
-even things like ctime or inode number (!) changed. Actual diff is printed out
-when you changed the file contents.
+$ cg-diff
 
-Of course you will want to commit. If you added any new files, do
+You can use the -r command to specify a single tree to compare against your
+current working directory:
 
-	cg-add newfile1 newfile2 ...
+$ cg-diff -r 9e734775f7c22d2f89943ad6c745571f1930105f
 
-first. Then examine your changes by cg-diff or just show what files did you
-change by
+More generally, cg-diff can be used to produce a diff between any two SHA1
+IDs (or tags). The most common way is with a single -r command line
+argument, specifying two trees by hash IDs:
 
-	cg-status
+$ cg-diff -r 9e734775f7c22d2f89943ad6c745571f1930105f:0397236d43e48e821cce5bbe6a80a1a56bb7cc3a
 
-and feel free to commit by
+The same command using tags would be:
 
-	cg-commit
+$ cg-diff -r v2.6.12-rc2:v2.6.12-rc3
 
-which expects the commit message on stdin.
+Or you could use two -r commands to accomplish the same thing:
 
-It is nice to be able to examine the commit history. We have tool for that too.
+$ cg-diff -r v2.6.12-rc2 -r v2.6.12-rc3
 
-	cg-log -r pasky
+Using the colon-separated form, leaving one SHA1 ID or tag name out implies
+that cg-diff should compare the specified tree to the current HEAD:
 
-will get you the history of my branch. cg-log with no arguments will default
-to the history of the current branch.
+$ cg-diff -r v2.6.12-rc2:
 
-If you want to start out new project, do (IN NEW DIRECTORY)
+compares Linux kernel version 2.6.12-rc2 with HEAD, creating a patch to
+convert the 2.6.12-rc2 tree into HEAD. To do the reverse, you simply put the
+':' at the other end of the string:
 
-	cg-init
+$ cg-diff -r :v2.6.12-rc2
 
-which will also do the initial commit, importing the content of the current
-directory if there is anything in it yet.
+This command compares HEAD to Linux kernel version 2.6.12-rc2, creating a
+patch to convert HEAD into the 2.6.12-rc2 tree.
 
-If you want to get someone else's project, do
+The cg-diff command can also take a -p argument.
 
-	cg-clone URL
+STUB - get more info on the -p arg
 
-(the URL will be available as branch "origin" for updating, etc).  cg-clone
-will create new repository for its work - if you want it to work in the current
-directory (like cg-init), pass it the '-s' argument first (like in our first
-cg-clone in this tutorial).
+        cg-export
 
-Note that we missed out a lot of stuff here. There is already support
-for merging (cg-merge), moving your tree to an older commit (cg-seek), etc.
+This command extracts the actual project under version control and puts it
+somewhere for you. Not the revision control history but the project files
+themselves. So if you have the Linux kernel in a git repository and you give
+a cg-export command, only the kernel files themselves, not the git
+repository files, will be exported.
 
-For quick reference, please see
+You must specify a destination for the export on the command line. This may
+have several different interpretations:
 
-	cg-help
+$ cg-export dirname
 
+In the command above, dirname is a directory name. In this case, cg-export
+exports the current state of the project to that directory.
 
-And for reference, my branch URL is:
+$ cg-export filename.tar
 
-	rsync://rsync.kernel.org/pub/scm/cogito/cogito.git
+In the above, filename.tar has a '.tar' extension, and so cg-export produces
+a tarball of the current state of the project. Other recognized extensions
+are '.tar.gz', '.tgz', and '.tar.bz2'.
 
-Note that this all is highly experimental and is likely break frequently. You
-are advised to track LKML and/or the git mailing list.
+You may specify an additional command line argument that is an SHA1 hash ID
+(or tag), to indicate the particular version of the tree you wish to export:
 
+$ cg-export filename.tgz 0397236d43e48e821cce5bbe6a80a1a56bb7cc3a
 
-Software requirements:
+or equivalently:
+
+$ cg-export filename.tgz v2.6.12-rc3
+
+This ability makes cg-export quite powerful. It is not just a tool for
+packaging the current state of the tree, it can package any past state as
+well.
+
+        cg-help
+
+This command is used to get help about other Cogito commands. The form is
+very simple. For instance, to get help on cg-pull, give the following
+command:
+
+$ cg-help cg-pull
+
+This is identical to giving this command as well:
+
+$ cg-pull --help
+
+Help for all other commands use an identical form.
+
+        cg-init
+
+This is used to initialize a new git repository. There are two cases: either
+you want to start a repository in an empty directory; or you want to start a
+repository in a full directory, using the existing files in that directory
+to seed the repository. In both cases the procedure is the same. Change
+directories into the directory you want to turn into the repository. Do not
+create a .git directory or anything weird like that. Just go into your
+target directory and give this command:
+
+$ cg-init
+
+Your editor will start up and you will be asked to write your first commit
+message. Make it a good one. Exit the editor. Welcome to Cogito.
+
+        cg-log
+
+This command generates changelog entries. Unless output is explicitly
+redirected, cg-log pipes all of its output to less. If invoked with no
+arguments, it shows all available changelog entries:
+
+$ cg-log
+
+You may use the -r command line argument to specify an SHA1 hash ID (or tag
+name), or a pair of these. cg-log will generate all log entries starting
+after the first, up to and including the second:
+
+$ cg-log -r v2.6.12-rc2:v2.6.12-rc3
+
+The above command shows all the log entries starting after the actual
+2.6.12-rc2 release, up to and including the entry marking the release of
+2.6.12-rc3. In other words, it produces the full changelog for 2.6.12-rc3.
+
+You may also use the -u command line argument, to specify the name - or part
+of the name - of the person who authored or committed the patch.
+
+$ cg-log -uStroesser
+
+Notice that there is no space between the -u and the name. If there are
+spaces in the name, you must use quotes, like this:
+
+$ cg-log -u"Irwin Fletcher"
+
+Whatever other arguments you give, you may also append a list of files on
+the command line. In that case, cg-log will output only the log entries of
+patches that altered those files.
+
+$ cg-log README Documentation/git.txt
+
+or
+
+$ cg-log -r v2.6.12-rc2:v2.6.12-rc3 -uLinus Makefile
+
+There are two options that control how output is displayed in cg-log. The -f
+option can be given with no arguments, to tell cg-log to include a list of
+all affected files with each changelog entry.
+
+$ cg-log -f -r v2.6.12-rc2:v2.6.12-rc3
+
+The other option to control output is -c. It can be given with no arguments,
+to cause cg-log to display its output in color.
+
+$ cg-log -c -f -r v2.6.12-rc2:v2.6.12-rc3
+
+Currently, the following changelog elements map to the following colors:
+
+header     Green   
+author     Cyan
+committer  Magenta
+files      Blue
+signoff    Yellow
+
+        cg-ls
+
+This command lists all the files in the repository, along with their current
+SHA1 hash ID and the type of data they represent to git (blob, tree).
+
+With no arguments, cg-ls operates on the current state of the repository. If
+given a commit ID or tree ID as a command line argument, it will list the
+files current as of that commit, or to that tree.
+
+STUB (this section needs filling out)
+
+        cg-merge
+
+STUB
+
+        cg-mkpatch
+
+STUB
+
+        cg-patch
+
+STUB
+
+        cg-pull
+
+See the quickstart section above
+
+        cg-restore
+
+STUB
+
+        cg-rm
+
+This command schedules a group of files for removal from the git repository,
+and also removes them right away from your working set of files. Although
+gone from your working set of files, the repository still considers them
+part of the tree until you give a cg-commit command.
+
+        cg-seek
+
+STUB
+
+        cg-status
+
+This command takes no arguments, and returns a list of files you have
+changed in your local tree, but that you have not yet committed with
+cg-commit. File additions and removals with cg-add and cg-rm are not listed.
+A sample usage follows:
+
+$ cg-status
+M cache.h
+$
+
+        cg-tag
+
+This command gives a convenient name of your choosing to a particular state
+of the repository, associating that name with the otherwise cumbersome hash
+ID. You may tag the current state of a repository, or you may specify a
+particular hash ID to tag from any previous state. In software development,
+a developer might tag a particular release with a version number. When Linus
+releases a new kernel, he tags it 'v2.6.12-rc4' or something similar.
+
+To tag the current state of a repository, just specify the name of the tag,
+as follows:
+
+$ cg-tag v2.6.12-rc4
+
+To tag a specific state from some time in the past, you must specify the
+SHA1 hash ID, like this:
+
+$ cg-tag v2.6.12-rc4 ebb5573ea8beaf000d4833735f3e53acb9af844c
+
+You can select a particular hash ID by looking at the 'commit' of the
+changelog entry representing the repository state you wish to tag.
+
+Tags are interchangeable with hash IDs in Cogito commands. Typically, to do
+a diff between two states of a repository, you must give a command like
+this:
+
+$ cg-diff -r 0397236d43e48e821cce5bbe6a80a1a56bb7cc3a:ebb5573ea8beaf000d4833735f3e53acb9af844c
+
+With tags, the same command can be given much more intuitively, like this:
+
+$ cg-diff -r v2.6.12-rc3:v2.6.12-rc4
+
+Both of the above examples will show you the diff between Linux kernel
+version 2.6.12-rc3 and 2.6.12-rc4.
+
+        cg-tag-ls
+
+This command takes no arguments, and lists all tags in a given repository in
+alphabetical order, along with their corresponding SHA1 hash IDs. Doing this
+on the current Cogito repository, for instance, produces the following
+output:
+
+$ cg-tag-ls
+cogito-0.10     4ed293bc0a5ffca9683e139cad499b69a4c4d569
+cogito-0.8      f9f0459b5b39cf83143c91ae39b4eaf187cf678a
+cogito-0.9      cc5517b4ea4134c296d4ce2b1d82700c44200c1e
+git-pasky-0.1   463d05c7c4fe7f24da29749f4c7f25893fc20b8c
+git-pasky-0.2   2c70421be7d88fbee49986d7a5584d1f010a25de
+git-pasky-0.3   d14925c87cdb6ca6345bcb3c8e34a2d659c79451
+git-pasky-0.4   b0bb73f33fc06cc5ff6fca0d2dfce484c5f191b7
+git-pasky-0.5   0ec59a771ff9d618a1b86e0cc1b93e3d9dad17a9
+git-pasky-0.6   b498dafca4dcc136294853d1de09fb64b0b0deea
+git-pasky-0.6.1 1690697813ffcfc35075859534a627699d07c613
+git-pasky-0.6.2 b21cee2236b494787204754960d6a5d2916dfeb4
+git-pasky-0.6.3 acc71aab89b4ae8d5f4a03c758cc4c2bc04a3229
+git-pasky-0.7   bc61d9a04dc39598014f38b0ad7422f0ceaf2cc9
+pull_from_pasky 11ed64c1b141c9ba397a1ca76aef2cd250976007
+$
+
+        cg-update
+
+See the quickstart section above.
 
-	bash, basic shell environment (sed, grep, textutils, ...)
-	diff, patch, RCS (the merge program from this package)
-	mktemp 1.5+ (Mandrake users beware!)
-	libssl
-	rsync
-	libcurl
 
 
 
 	The "core GIT"
 	~~~~~~~~~~~~~~
 
-This is a stupid (but extremely fast) directory content manager.  It
+	GIT - the stupid content tracker
+
+"git" can mean anything, depending on your mood.
+
+ - random three-letter combination that is pronounceable, and not
+   actually used by any common UNIX command.  The fact that it is a
+   mispronunciation of "get" may or may not be relevant.
+ - stupid. contemptible and despicable. simple. Take your pick from the
+   dictionary of slang.
+ - "global information tracker": you're in a good mood, and it actually
+   works for you. Angels sing, and a light suddenly fills the room. 
+ - "goddamn idiotic truckload of sh*t": when it breaks
+
+The GIT itself is merely an extremely fast and flexible filesystem-based
+database designed to store directory trees with regard to their history.
+The top layer is a SCM-like tool Cogito which enables human beings to work
+with the database in a manner to a degree similar to other SCM tools (like
+CVS, BitKeeper or Monotone).
+
+Git is a stupid (but extremely fast) directory content manager.  It
 doesn't do a whole lot, but what it _does_ do is track directory
 contents efficiently.
 


^ permalink raw reply

* README rewrite
From: Zack Brown @ 2005-05-15  4:42 UTC (permalink / raw)
  To: Petr Baudis; +Cc: git

Hi Petr,

This patch is a complete rewrite of the Cogito section of the README file.
Commands are explained in detail, with a quickstart section at the top and a
full command reference below.

Signed-off-by: Zack Brown <zbrown@tumblerings.org>

README: needs update
Index: README
===================================================================
--- 4ef3de6ae44888d83e8c00326ddcc9f40cbd12e2/README  (mode:100644)
+++ uncommitted/README  (mode:100644)
@@ -1,164 +1,656 @@
-	GIT - the stupid content tracker
+                Cogito
 
-"git" can mean anything, depending on your mood.
+Cogito is a version control system layered on top of the git
+content-tracking filesystem. This document first describes some quick ways
+to get started using Cogito, then goes over each available command one by
+one.
 
- - random three-letter combination that is pronounceable, and not
-   actually used by any common UNIX command.  The fact that it is a
-   mispronunciation of "get" may or may not be relevant.
- - stupid. contemptible and despicable. simple. Take your pick from the
-   dictionary of slang.
- - "global information tracker": you're in a good mood, and it actually
-   works for you. Angels sing, and a light suddenly fills the room. 
- - "goddamn idiotic truckload of sh*t": when it breaks
+            Quickstart
 
-The GIT itself is merely an extremely fast and flexible filesystem-based
-database designed to store directory trees with regard to their history.
-The top layer is a SCM-like tool Cogito which enables human beings to work
-with the database in a manner to a degree similar to other SCM tools (like
-CVS, BitKeeper or Monotone).
+        Downloading Cogito From Scratch
+
+Cogito can be obtained as a tarball from
+
+http://www.kernel.org/pub/software/scm/cogito/
+
+Download and unpack the latest version, build with make, put the executables
+somewhere in your $PATH (or add your Cogito directory itself to your $PATH),
+and you're ready to go!
+
+The following tools are required by Cogito:
+
+bash
+basic shell environment (sed, grep, textutils, ...)
+diff
+patch
+RCS (the merge program from this package)
+mktemp 1.5+ (Mandrake users beware!)
+libssl
+rsync
+libcurl
+
+        Starting A Fresh git Repository
+
+If you want to start your own project using Cogito, there are two basic ways
+to do this. You may start a fresh repository with no files in it, or you may
+take an existing directory tree and turn it into a git repository.
+
+    Starting An Empty Repository
+
+To create a new repository with no files in it, cd into an empty directory,
+and give the following command:
+
+$ cg-init
+
+Your editor will start up, and you will be asked to type in an initial
+commit description. Type something cute, and exit your editor.
+
+That's it! You're now in your own git repository. Notice there is now a git
+.directory. Go into it and look around, but don't change anything in
+there. That's what Cogito commands are for.
+
+    Turning An Existing Directory Into A Repository
+
+If you have a directory full of files, you can easily turn this into a
+git repository. In fact, it is virtually the same as starting an empty
+repository. Just cd into the directory you want converted into a git
+repository, and give the following command:
+
+$ cg-init
+
+Your editor starts up, you type in an initial commit message, exit your
+editor, and you're good to go. All of the files and directories within that
+directory are now part of a git archive.
+
+        Accessing Someone Else's git Repository
+
+    Creating The Repository
+
+If you want to get started tracking an outside git repository, you first
+must have Cogito's executables on your $PATH. Next, you need the URL (or
+local directory path) of the repository you want to track. You can't just
+use the URL of a tarball, like the one given above for the Cogito source.
+The URL must point specifically to a .git directory somewhere. For instance,
+the URL for Cogito's self-hosting repository is
+
+rsync://rsync.kernel.org/pub/scm/cogito/cogito.git
+
+Notice that the final filename, 'cogito.git', is not called '.git'. That is
+fine. It's still a .git directory.
+
+To clone the repository to your local filesystem, use the cg-clone command.
+cg-clone can be told to create a new directory for your repository, or to
+drop the repository into the current directory.
+
+To have a new directory created, just include the directory in the command,
+as follows:
+
+$ cg-clone rsync://rsync.kernel.org/pub/scm/cogito/cogito.git cogitodir
+
+You will see a whole bunch of output, and when it is over, there will be a
+new directory called 'cogitodir' (or whatever name you chose) in the current
+directory. cd into it. Because we used the Cogito URL, you will see the
+Cogito source tree, with its own .git directory keeping track of everything.
+
+If, instead, you want to clone the repository to the current directory,
+first make sure you are in an empty directory. Then give the following
+command:
+
+$ cg-clone -s rsync://rsync.kernel.org/pub/scm/cogito/cogito.git cogitodir
+
+When you get your prompt back, do an ls to see the source tree and .git
+directory.
+
+    Tracking The Repository
+
+Of course, once you have cloned a repository, you don't just want to leave
+it at that. The upstream sources are constantly being updated, and you want
+to follow these updates. To do this, cd into the repository directory (not
+the .git directory, but the directory that contains the .git directory), and
+give the following command:
+
+$ cg-update
+
+You don't use a URL anymore. Cogito knows which tree you're tracking,
+because this information is stored in the .git directory. The above command
+will track the 'origin' branch, which is the primary branch of development.
+But cg-update can also be used to track specific branches. See below for
+more discussion of branches, and how to track them.
+
+When you give the above cg-update command, this performed two actions.
+First, it pulled all new changes from the upstream repository into your
+local repository. At that point, the changes exist in your local repository
+as part of the project's history. The changes themselves are not actually
+visible in the files you see, but reside in the .git directory's awareness.
+The second thing cg-update does is to merge these changes into the files you
+see and work with. The end result is that, when the cg-update has finished,
+you will see all the upstream changes reflected in your local files, and the
+.git directory will be aware of the history of those changes as well.
+
+It may be that you want to be aware of the history of the upstream work, but
+you don't yet want those changes merged with your own local files. To do
+this, give the following command:
+
+$ cg-pull
+
+This does the first part of cg-update's behavior, but skips the second part.
+Now your local files have not been changed, but your .git directory has been
+updated with the history of all the changes that have occurred in the
+upstream sources.
+
+Using cg-pull is useful for a variety of purposes, for instance if you want
+to construct a diff against the latest version of the upstream sources, but
+don't want those changes to disturb your ongoing work. cg-pull will update
+your .git directory with the history you need to construct your diff,
+without merging that history into your tree, potentially breaking your
+changes.
+
+Typically, if you are not making changes to a repository yourself, but just
+want the latest version of a given project for your own use, you would use
+cg-update. cg-pull is strictly for development work.
+
+Once you've done a cg-pull, you may decide you want to merge after all. In
+this case a cg-update command will do the trick, however you will also
+update your local files with any further upstream changes that have occurred
+since your cg-pull.
+
+        Getting Help
+
+Cogito commands come with their own helpful documentation. To get help on
+cg-update, for example, give this command:
+
+$ cg-pull --help
+
+or, for the same information, try this:
+
+$ cg-help cg-pull
+
+            Command Reference
+
+        Caveats
+
+    What are those cg-Xes?
+
+There are three executables, cg-Xdiffdo, cg-Xlib, and cg-Xmergefile, that
+are not meant to be used from the command line. They provide a library of
+generic functions used by many of the real cg-* commands. You can safely
+ignore them, unless you want to contribute to Cogito development.
+
+    What about file renames?
+
+File renaming (and tracking the history of a file from name to name) is
+being worked on. git provides a wonderful, elegant way to track content as
+it moves from file to file, and renames should be a special case of this.
+
+    Can I give Cogito commands from a subdirectory?
+
+Cogito currently requires that commands be given from the base directory,
+the one containing the .git directory. Patches have been submitted to
+implement the ability to give Cogito commands from subdirectories within the
+repository, but Linus prefers the current bahavior.
+
+        cg-add
+
+This command is used to add files to the git repository. It takes a list of
+files on the command line, and schedules them for addition. To actually add
+them, however, you must subsequently give a cg-commit command.
+
+$ cg-add file1 file2 dir1/file3 dir1/file4 dir2/dir3/file5
+
+The above command schedules file1, file2, file3, file4, and file5 to be
+added to the repository at the next cg-commit.
+
+Notice that you never need to add directories to a repository, in fact
+Cogito won't let you. Directories are added automatically when you add the
+files that are inside them. So you can do something like this:
+
+$ mkdir testdir
+$ echo "testtext" > testdir/testfile
+$ cg-add testdir/testfile
+$ cg-commit
+
+and the testdir directory and testfile file will both be added to the
+repository. If you then do a cg-seek to look at an earlier version of the
+respository, both the file and the directory will be gone.
+
+        cg-admin-lsobj
+
+STUB
+
+        cg-admin-uncommit
+
+STUB
+
+        cg-branch-add
+
+STUB
+
+        cg-branch-ls
+
+STUB
+
+        cg-cancel
+
+This undoes all the changes you have made but not committed to your
+repository. Changes you have already committed are kept. All others are
+reverted to their previous form.
+
+If you have given any cg-add commands, these are also undone in the sense
+that the files and directories will no longer be added on a cg-commit. The
+files and directories themselves are not deleted by a cg-cancel.
+
+        cg-clone
+
+This checks out a remote repository into a local filesystem. It is only used
+for the initial creation of the local repository. Subsequent updates to
+track the upstream sources are done with cg-update or cg-pull.
+
+In its simplest form, cg-clone takes a URL or directory path to a remote
+repository:
+
+$ cg-clone rsync://rsync.kernel.org/pub/scm/cogito/cogito.git
 
+The above command interprets the URL and takes the base directory (in this
+case 'cogito') as the target for the new repository. If the directory
+already exists within the current directory, cg-clone exits with an error
+message. Otherwise this directory is created within the current directory.
+cg-clone then clones the upstream repository into that directory.
 
+It's also possible to specify the target directory by hand on the command
+line, as follows:
 
-	Cogito
-	~~~~~~
+$ cg-clone rsync://rsync.kernel.org/pub/scm/cogito/cogito.git targetdir
 
-This currently simply describes what should you do when you get a tarball
-of Cogito and start to use it and hack upon it. It can give you some guide,
-but the documentation should be certainly consolidated and rewritten.
+If targetdir already exists, cg-clone will exit again with an error message.
+Otherwise, targetdir is created, and the upstream repository is cloned into
+it.
 
-Build it by make, make sure the scripts are in $PATH.
+If you want to clone the upstream sources into the current directory, use
+the -s option:
 
-If, after unpacking the tarball, you do not have the .git subdirectory in the
-tarball root, you
+$ cg-clone -s rsync://rsync.kernel.org/pub/scm/cogito/cogito.git
 
-	cg-clone -s rsync://rsync.kernel.org/pub/scm/cogito/cogito.git
+This will not create a new directory anywhere, but will just create the
+repository directly into the current directory. Any files or directories
+already in the current directory will not be overwritten, and files of the
+same name will retain their old contents. Typically, you never want to use
+the -s option in a directory with existing files or subdirectories.
 
-in that directory, and
+        cg-commit
 
-	cg-branch-add pasky rsync://rsync.kernel.org/pub/scm/cogito/cogito.git
+This command is used after you have edited files in a repository, and now
+want to include your changes in the project history. After a cg-commit, your
+changes will have a changelog entry, including your identity, the date of
+the change, and other information.
 
-(there is already the same branch called "origin" created by cg-clone, however
-we expect the branch name to be "pasky" for the result of the tutorial;
-alternatively, just use "origin" everywhere instead of "pasky").
+Typically you do not need to give any command line options to cg-commit, but
+just use it in its simplest form:
 
-If you already have the .git subdirectory, update it to the latest version by
+$ cg-commit
 
-	cg-update pasky
+This will fire up your editor and ask for a changelog entry. If you leave
+this text blank, a changelog entry will still be created, but with no
+explanatory text. When you exit your editor, your changed files and
+changelog entry are included in the history of the repository, and are
+subject to full version control.
 
-(and repeat that after some time to get the future updates - but see below).
-Then build it again, doing
+There are several ways to avoid dealing with an editor at commit time.
+cg-commit accepts changelog entries from standard input:
 
-	make
+$ echo "my first changelog entry" | cg-commit
 
-and...  well, that's it. Play around with it a bit. ;-)
+You can also specify your changelog entry with the -m option to cg-commit:
 
-You can get my latest changes by doing:
+$ cg-commit -m"my first changelog entry"
 
-	cg-update pasky
+If a changelog entry is sent via standard input, and another one is included
+in a -m option, the entry from standard input is appended with no blank line
+after the entry from the -m option.
 
-If you did some local commits in the meantime, Cogito will attempt to merge
-them with the pasky branch. You then need to check that the merging went
-correctly and without conflicts, possibly do merge-related fixes, and then
-record the merge with cg-commit (if the merge was clean, Cogito will commit
-automatically).
+Multiple -m options can also be given, and they will each be appended, with
+a blank line between, after the one before in the changelog entry.
 
-Sometimes, you will just want to bring the latest stuff from my branch, but not
-merge it (e.g. you might want only to diff against it). Do that by
+A -e option also exists, to force an editor to come up for a commit message,
+even if -m options are present, or if there is data coming from standard
+input. In this case, all input from standard input or -m options is appended
+with a blank line after the text typed into the editor.
 
-	cg-pull pasky
+A -E option also exists and behaves identically to -e, except it will force
+the commit even if the default commit message is not changed.
 
-If there are any changes, two IDs will be printed (I mean the line saying
-"Tree change"). Pass those as parameters to cg-diff and you will get a diff
-describing changes from the last time you pulled. You can also
+A -C option also exists, but it is for internal purposes. You can safely
+ignore it.
 
-	cg-diff -r pasky:HEAD
+There are several environment variables you may use to control the
+authentication information included with the changelog entry. Typically,
+Cogito uses getpwuid(getuid()) to identify the user. This can be overridden
+with these variables:
 
-which will show changes between my and your branch.
+GIT_AUTHOR_NAME       Author's name
+GIT_AUTHOR_EMAIL      Author's e-mail address
+GIT_AUTHOR_DATE       Date, perhaps from a patch e-mail
+GIT_COMMITTER_NAME    Committer's name
+GIT_COMMITTER_EMAIL   Committer's e-mail address
 
-Note that you can also access the Linus' official branch, just by specifying
-'linus' instead of 'pasky'. You can of course add more branches by:
+In the above variables - and in the changelog entries - the author is the
+person who actually wrote a given patch, and the commiter is the person who
+actually gave the command to include this patch in the repository. If you
+are just working on your own repository, or if you commit your own patches,
+then the author and committer are both you.
 
-	cg-branch-add name rsyncurl
+        cg-diff
 
-(the rsyncurl can have a fragment part identifying a branch inside of the
-repository accessible over rsync).  When you do some local changes, you can do
+This compares two trees and outputs a diff, suitable for feeding into the
+patch program. If there is no difference between the trees, cg-diff just
+outputs "ok".
 
-	cg-diff
+With no arguments, it compares the state of your working tree, including all
+your uncommitted changes, with the state of the tree at the last commit. The
+result in this case is a diff showing only the changes you have not yet
+committed. To do this, give the following command:
 
-to display them. "ok" means it's identical, while hash printed means that there
-is some difference. This is a little troublesome so far, since it doesn't like
-even things like ctime or inode number (!) changed. Actual diff is printed out
-when you changed the file contents.
+$ cg-diff
 
-Of course you will want to commit. If you added any new files, do
+You can use the -r command to specify a single tree to compare against your
+current working directory:
 
-	cg-add newfile1 newfile2 ...
+$ cg-diff -r 9e734775f7c22d2f89943ad6c745571f1930105f
 
-first. Then examine your changes by cg-diff or just show what files did you
-change by
+More generally, cg-diff can be used to produce a diff between any two SHA1
+IDs (or tags). The most common way is with a single -r command line
+argument, specifying two trees by hash IDs:
 
-	cg-status
+$ cg-diff -r 9e734775f7c22d2f89943ad6c745571f1930105f:0397236d43e48e821cce5bbe6a80a1a56bb7cc3a
 
-and feel free to commit by
+The same command using tags would be:
 
-	cg-commit
+$ cg-diff -r v2.6.12-rc2:v2.6.12-rc3
 
-which expects the commit message on stdin.
+Or you could use two -r commands to accomplish the same thing:
 
-It is nice to be able to examine the commit history. We have tool for that too.
+$ cg-diff -r v2.6.12-rc2 -r v2.6.12-rc3
 
-	cg-log -r pasky
+Using the colon-separated form, leaving one SHA1 ID or tag name out implies
+that cg-diff should compare the specified tree to the current HEAD:
 
-will get you the history of my branch. cg-log with no arguments will default
-to the history of the current branch.
+$ cg-diff -r v2.6.12-rc2:
 
-If you want to start out new project, do (IN NEW DIRECTORY)
+compares Linux kernel version 2.6.12-rc2 with HEAD, creating a patch to
+convert the 2.6.12-rc2 tree into HEAD. To do the reverse, you simply put the
+':' at the other end of the string:
 
-	cg-init
+$ cg-diff -r :v2.6.12-rc2
 
-which will also do the initial commit, importing the content of the current
-directory if there is anything in it yet.
+This command compares HEAD to Linux kernel version 2.6.12-rc2, creating a
+patch to convert HEAD into the 2.6.12-rc2 tree.
 
-If you want to get someone else's project, do
+The cg-diff command can also take a -p argument.
 
-	cg-clone URL
+STUB - get more info on the -p arg
 
-(the URL will be available as branch "origin" for updating, etc).  cg-clone
-will create new repository for its work - if you want it to work in the current
-directory (like cg-init), pass it the '-s' argument first (like in our first
-cg-clone in this tutorial).
+        cg-export
 
-Note that we missed out a lot of stuff here. There is already support
-for merging (cg-merge), moving your tree to an older commit (cg-seek), etc.
+This command extracts the actual project under version control and puts it
+somewhere for you. Not the revision control history but the project files
+themselves. So if you have the Linux kernel in a git repository and you give
+a cg-export command, only the kernel files themselves, not the git
+repository files, will be exported.
 
-For quick reference, please see
+You must specify a destination for the export on the command line. This may
+have several different interpretations:
 
-	cg-help
+$ cg-export dirname
 
+In the command above, dirname is a directory name. In this case, cg-export
+exports the current state of the project to that directory.
 
-And for reference, my branch URL is:
+$ cg-export filename.tar
 
-	rsync://rsync.kernel.org/pub/scm/cogito/cogito.git
+In the above, filename.tar has a '.tar' extension, and so cg-export produces
+a tarball of the current state of the project. Other recognized extensions
+are '.tar.gz', '.tgz', and '.tar.bz2'.
 
-Note that this all is highly experimental and is likely break frequently. You
-are advised to track LKML and/or the git mailing list.
+You may specify an additional command line argument that is an SHA1 hash ID
+(or tag), to indicate the particular version of the tree you wish to export:
 
+$ cg-export filename.tgz 0397236d43e48e821cce5bbe6a80a1a56bb7cc3a
 
-Software requirements:
+or equivalently:
+
+$ cg-export filename.tgz v2.6.12-rc3
+
+This ability makes cg-export quite powerful. It is not just a tool for
+packaging the current state of the tree, it can package any past state as
+well.
+
+        cg-help
+
+This command is used to get help about other Cogito commands. The form is
+very simple. For instance, to get help on cg-pull, give the following
+command:
+
+$ cg-help cg-pull
+
+This is identical to giving this command as well:
+
+$ cg-pull --help
+
+Help for all other commands use an identical form.
+
+        cg-init
+
+This is used to initialize a new git repository. There are two cases: either
+you want to start a repository in an empty directory; or you want to start a
+repository in a full directory, using the existing files in that directory
+to seed the repository. In both cases the procedure is the same. Change
+directories into the directory you want to turn into the repository. Do not
+create a .git directory or anything weird like that. Just go into your
+target directory and give this command:
+
+$ cg-init
+
+Your editor will start up and you will be asked to write your first commit
+message. Make it a good one. Exit the editor. Welcome to Cogito.
+
+        cg-log
+
+This command generates changelog entries. Unless output is explicitly
+redirected, cg-log pipes all of its output to less. If invoked with no
+arguments, it shows all available changelog entries:
+
+$ cg-log
+
+You may use the -r command line argument to specify an SHA1 hash ID (or tag
+name), or a pair of these. cg-log will generate all log entries starting
+after the first, up to and including the second:
+
+$ cg-log -r v2.6.12-rc2:v2.6.12-rc3
+
+The above command shows all the log entries starting after the actual
+2.6.12-rc2 release, up to and including the entry marking the release of
+2.6.12-rc3. In other words, it produces the full changelog for 2.6.12-rc3.
+
+You may also use the -u command line argument, to specify the name - or part
+of the name - of the person who authored or committed the patch.
+
+$ cg-log -uStroesser
+
+Notice that there is no space between the -u and the name. If there are
+spaces in the name, you must use quotes, like this:
+
+$ cg-log -u"Irwin Fletcher"
+
+Whatever other arguments you give, you may also append a list of files on
+the command line. In that case, cg-log will output only the log entries of
+patches that altered those files.
+
+$ cg-log README Documentation/git.txt
+
+or
+
+$ cg-log -r v2.6.12-rc2:v2.6.12-rc3 -uLinus Makefile
+
+There are two options that control how output is displayed in cg-log. The -f
+option can be given with no arguments, to tell cg-log to include a list of
+all affected files with each changelog entry.
+
+$ cg-log -f -r v2.6.12-rc2:v2.6.12-rc3
+
+The other option to control output is -c. It can be given with no arguments,
+to cause cg-log to display its output in color.
+
+$ cg-log -c -f -r v2.6.12-rc2:v2.6.12-rc3
+
+Currently, the following changelog elements map to the following colors:
+
+header     Green   
+author     Cyan
+committer  Magenta
+files      Blue
+signoff    Yellow
+
+        cg-ls
+
+This command lists all the files in the repository, along with their current
+SHA1 hash ID and the type of data they represent to git (blob, tree).
+
+With no arguments, cg-ls operates on the current state of the repository. If
+given a commit ID or tree ID as a command line argument, it will list the
+files current as of that commit, or to that tree.
+
+STUB (this section needs filling out)
+
+        cg-merge
+
+STUB
+
+        cg-mkpatch
+
+STUB
+
+        cg-patch
+
+STUB
+
+        cg-pull
+
+See the quickstart section above
+
+        cg-restore
+
+STUB
+
+        cg-rm
+
+This command schedules a group of files for removal from the git repository,
+and also removes them right away from your working set of files. Although
+gone from your working set of files, the repository still considers them
+part of the tree until you give a cg-commit command.
+
+        cg-seek
+
+STUB
+
+        cg-status
+
+This command takes no arguments, and returns a list of files you have
+changed in your local tree, but that you have not yet committed with
+cg-commit. File additions and removals with cg-add and cg-rm are not listed.
+A sample usage follows:
+
+$ cg-status
+M cache.h
+$
+
+        cg-tag
+
+This command gives a convenient name of your choosing to a particular state
+of the repository, associating that name with the otherwise cumbersome hash
+ID. You may tag the current state of a repository, or you may specify a
+particular hash ID to tag from any previous state. In software development,
+a developer might tag a particular release with a version number. When Linus
+releases a new kernel, he tags it 'v2.6.12-rc4' or something similar.
+
+To tag the current state of a repository, just specify the name of the tag,
+as follows:
+
+$ cg-tag v2.6.12-rc4
+
+To tag a specific state from some time in the past, you must specify the
+SHA1 hash ID, like this:
+
+$ cg-tag v2.6.12-rc4 ebb5573ea8beaf000d4833735f3e53acb9af844c
+
+You can select a particular hash ID by looking at the 'commit' of the
+changelog entry representing the repository state you wish to tag.
+
+Tags are interchangeable with hash IDs in Cogito commands. Typically, to do
+a diff between two states of a repository, you must give a command like
+this:
+
+$ cg-diff -r 0397236d43e48e821cce5bbe6a80a1a56bb7cc3a:ebb5573ea8beaf000d4833735f3e53acb9af844c
+
+With tags, the same command can be given much more intuitively, like this:
+
+$ cg-diff -r v2.6.12-rc3:v2.6.12-rc4
+
+Both of the above examples will show you the diff between Linux kernel
+version 2.6.12-rc3 and 2.6.12-rc4.
+
+        cg-tag-ls
+
+This command takes no arguments, and lists all tags in a given repository in
+alphabetical order, along with their corresponding SHA1 hash IDs. Doing this
+on the current Cogito repository, for instance, produces the following
+output:
+
+$ cg-tag-ls
+cogito-0.10     4ed293bc0a5ffca9683e139cad499b69a4c4d569
+cogito-0.8      f9f0459b5b39cf83143c91ae39b4eaf187cf678a
+cogito-0.9      cc5517b4ea4134c296d4ce2b1d82700c44200c1e
+git-pasky-0.1   463d05c7c4fe7f24da29749f4c7f25893fc20b8c
+git-pasky-0.2   2c70421be7d88fbee49986d7a5584d1f010a25de
+git-pasky-0.3   d14925c87cdb6ca6345bcb3c8e34a2d659c79451
+git-pasky-0.4   b0bb73f33fc06cc5ff6fca0d2dfce484c5f191b7
+git-pasky-0.5   0ec59a771ff9d618a1b86e0cc1b93e3d9dad17a9
+git-pasky-0.6   b498dafca4dcc136294853d1de09fb64b0b0deea
+git-pasky-0.6.1 1690697813ffcfc35075859534a627699d07c613
+git-pasky-0.6.2 b21cee2236b494787204754960d6a5d2916dfeb4
+git-pasky-0.6.3 acc71aab89b4ae8d5f4a03c758cc4c2bc04a3229
+git-pasky-0.7   bc61d9a04dc39598014f38b0ad7422f0ceaf2cc9
+pull_from_pasky 11ed64c1b141c9ba397a1ca76aef2cd250976007
+$
+
+        cg-update
+
+See the quickstart section above.
 
-	bash, basic shell environment (sed, grep, textutils, ...)
-	diff, patch, RCS (the merge program from this package)
-	mktemp 1.5+ (Mandrake users beware!)
-	libssl
-	rsync
-	libcurl
 
 
 
 	The "core GIT"
 	~~~~~~~~~~~~~~
 
-This is a stupid (but extremely fast) directory content manager.  It
+	GIT - the stupid content tracker
+
+"git" can mean anything, depending on your mood.
+
+ - random three-letter combination that is pronounceable, and not
+   actually used by any common UNIX command.  The fact that it is a
+   mispronunciation of "get" may or may not be relevant.
+ - stupid. contemptible and despicable. simple. Take your pick from the
+   dictionary of slang.
+ - "global information tracker": you're in a good mood, and it actually
+   works for you. Angels sing, and a light suddenly fills the room. 
+ - "goddamn idiotic truckload of sh*t": when it breaks
+
+The GIT itself is merely an extremely fast and flexible filesystem-based
+database designed to store directory trees with regard to their history.
+The top layer is a SCM-like tool Cogito which enables human beings to work
+with the database in a manner to a degree similar to other SCM tools (like
+CVS, BitKeeper or Monotone).
+
+Git is a stupid (but extremely fast) directory content manager.  It
 doesn't do a whole lot, but what it _does_ do is track directory
 contents efficiently.
 


-- 
Zack Brown

^ permalink raw reply

* Re: [PATCH 0/4] Pulling refs files
From: Daniel Barkalow @ 2005-05-15  3:23 UTC (permalink / raw)
  To: Petr Baudis; +Cc: git, Linus Torvalds
In-Reply-To: <20050513233738.GL32232@pasky.ji.cz>

On Sat, 14 May 2005, Petr Baudis wrote:

> So what about just something like
> 
> 	git-wormhole-pull remote:refs/head/master wormhole://localhost/
> 
> That is, you could just specify remote:path_relative_to_url instead of
> SHA1 id as the commit.

Do you have any sensible alternatives to "remote:refs/<something>" in
mind? I suppose that "remote:HEAD" would also work. How are you thinking
of having the value get written locally?

Do you also have some idea for user-invoked rpush? It has to call
something that writes the value on the other side (and I'd ideally like it
to do the update atomically and locked against other clients). This series
uses the same mechanism to write it that it uses to write hashes fetched
from remote machines.

	-Daniel
*This .sig left intentionally blank*


^ permalink raw reply

* Re: [RFD] Ignore rules
From: Jon Seymour @ 2005-05-15  1:11 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Petr Baudis, David Greaves, torvalds, GIT Mailing Lists
In-Reply-To: <7vsm0py8vz.fsf@assigned-by-dhcp.cox.net>

Is there value in:

a. pushing the ignore logic into the core git tools such as git-ls-files

b. including the current ignore .* rule as a default ignore rule that
can be overridden by a .gitignore file


jon.
-- 
homepage: http://www.zeta.org.au/~jon/
blog: http://orwelliantremors.blogspot.com/

^ permalink raw reply

* Re: [PATCH] Resurrect diff-tree-helper -R
From: Petr Baudis @ 2005-05-14 23:35 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Linus Torvalds, git
In-Reply-To: <7vu0l5zsb4.fsf@assigned-by-dhcp.cox.net>

Dear diary, on Sat, May 14, 2005 at 06:27:27PM CEST, I got a letter
where Junio C Hamano <junkio@cox.net> told me that...
> >>>>> "PB" == Petr Baudis <pasky@ucw.cz> writes:
> 
> Now I understand which discussion I was missing ;-).
> 
> PB> For humans I'd say "Mode change" instead of "mode" would be better, and
> PB> for machines I still think "@" would be better than "#". "#" can occur
> PB> quite naturally in some code snippets or whatever pasted to the commit
> PB> message, which is extremely unlikely for "@". What are the advantages
> PB> of "#"?
> 
> Wait a minute.  Aren't we scanning starting from the first
> '---\n'?  Why does what's in commit message matter?

Ok, that changes the whole situation. I'll take your patches as they are
now in that case. :-)

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
C++: an octopus made by nailing extra legs onto a dog. -- Steve Taylor

^ permalink raw reply

* git-rev-list  in local commit order
From: Sean @ 2005-05-14 21:44 UTC (permalink / raw)
  To: git

[-- Attachment #1: Type: text/plain, Size: 1317 bytes --]

Attached is a preliminary hackish patch to sort git-rev-list in local
commit order.   While I don't know how useful this really is, it's
presented as an alternative to the repo-id proposal.  This will work even
if the branch happens to be from a single repository, where repo-id will
not.  However, shared commit objects can cause problems so for best
results use private commit objects for each repository.

For purposes of testing, this patch changes the Cogito default of linking
objects to copying, for local repository pull operations.   This patch
will work with _existing_ repositories where local commit times have been
maintained.

Also attached, is a little test script that demonstrates the local commit
time order.  After running the test script, you can use the cg-log command
in each of the M and R directories to see the difference even though the
two repositories share a head commit.

This patch is not nearly ready for inclusion anywhere just meant for
comment.  It is based off Petr's cogito tree (commit
fa6e9eb368e949e78c4e66217461cf624b52b0a2).

 cache.h     |    1
 cg-pull     |    4 -
 commit.c    |  121
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 commit.h    |    6 ++
 rev-list.c  |    2
 sha1_file.c |    8 +++
 6 files changed, 137 insertions(+), 5 deletions(-)

Sean


[-- Attachment #2: local-rev-list-v1.patch --]
[-- Type: application/octet-stream, Size: 6552 bytes --]

Index: cache.h
===================================================================
--- a/cache.h  (mode:100644)
+++ b/cache.h  (mode:100644)
@@ -157,6 +157,7 @@
 extern int write_sha1_from_fd(const unsigned char *sha1, int fd);
 
 extern int has_sha1_file(const unsigned char *sha1);
+extern unsigned long sha1_local_date(const unsigned char *sha1);
 
 /* Convert to/from hex/sha1 representation */
 extern int get_sha1(const char *str, unsigned char *sha1);
Index: cg-pull
===================================================================
--- a/cg-pull  (mode:100755)
+++ b/cg-pull  (mode:100755)
@@ -143,7 +143,7 @@
 	[ "$1" = "-i" ] && shift
 	[ "$1" = "-s" ] && shift
 
-	cp_flags_l="-va"
+	cp_flags_l="-vdR"
 	if [ "$1" = "-u" ]; then
 		cp_flags_l="$cp_flags_l -lu"
 		shift
@@ -163,7 +163,7 @@
 }
 
 pull_local () {
-	git-local-pull -a -l -v "$(cat "$_git/refs/heads/$1")" "$2"
+	git-local-pull -a -v "$(cat "$_git/refs/heads/$1")" "$2"
 }
 
 if echo "$uri" | grep -q "^http://"; then
Index: commit.c
===================================================================
--- a/commit.c  (mode:100644)
+++ b/commit.c  (mode:100644)
@@ -2,6 +2,7 @@
 #include "cache.h"
 #include <string.h>
 #include <limits.h>
+#include <stdlib.h>
 
 const char *commit_type = "commit";
 
@@ -13,6 +14,7 @@
 		memset(ret, 0, sizeof(struct commit));
 		created_object(sha1, &ret->object);
 		ret->object.type = commit_type;
+		ret->local_date = sha1_local_date(sha1);
 		return ret;
 	}
 	if (obj->type != commit_type) {
@@ -41,6 +43,18 @@
 	return date;
 }
 
+static void insert_by_local_date(struct commit_list **list, struct commit *item)
+{
+	struct commit_list **pp = list;
+	struct commit_list *p;
+	while ((p = *pp) != NULL) {
+		if (p->item->local_date > item->local_date) 
+			break;
+		pp = &p->next;
+	}
+	commit_list_insert(item, pp);
+}
+
 int parse_commit_buffer(struct commit *item, void *buffer, unsigned long size)
 {
 	void *bufptr = buffer;
@@ -58,12 +72,13 @@
 	       !get_sha1_hex(bufptr + 7, parent)) {
 		struct commit *new_parent = lookup_commit(parent);
 		if (new_parent) {
-			commit_list_insert(new_parent, &item->parents);
+ 			insert_by_local_date(&item->parents, new_parent);
 			add_ref(&item->object, &new_parent->object);
 		}
 		bufptr += 48;
 	}
 	item->date = parse_commit_date(bufptr);
+	item->merge_nodes = NULL;
 	return 0;
 }
 
@@ -152,3 +167,107 @@
 	}
 	return ret;
 }
+
+struct commit_list *copy_commit_list(struct commit_list *list)
+{
+	struct commit_list *copy = NULL;
+	while (list) {
+		commit_list_insert(list->item, &copy); 
+		list = list->next;
+	}
+	return copy;
+}
+
+int found_on_list(struct commit *item, struct commit_list *list)
+{
+	while (list) {
+		if (list->item == item)
+			return 1;
+		list = list->next;
+	}
+	return 0;
+}
+
+static struct commit *process_local_list(struct commit_list **list_p, 
+					int this_mark, int other_mark)
+{
+	struct commit *item = (*list_p)->item;
+
+	if (item->object.flags & other_mark) {
+		return item;
+	} else {
+		pop_most_recent_commit(list_p, this_mark);
+	}
+	return NULL;
+}
+
+struct commit *common_local_ancestor(struct commit *rev1, struct commit *rev2)
+{
+	struct commit_list *rev1list = NULL;
+	struct commit_list *rev2list = NULL;
+
+	commit_list_insert(rev1, &rev1list); rev1->object.flags |= 0x1;
+	commit_list_insert(rev2, &rev2list); rev2->object.flags |= 0x2;
+	parse_commit(rev1); parse_commit(rev2);
+
+	while (rev1list || rev2list) {
+		struct commit *ret;
+		if (!rev1list) {
+			// process 2
+			ret = process_local_list(&rev2list, 0x2, 0x1);
+		} else if (!rev2list) {
+			// process 1
+			ret = process_local_list(&rev1list, 0x1, 0x2);
+		} else if (rev1list->item->local_date 
+				< rev2list->item->local_date) {
+			// process 2
+			ret = process_local_list(&rev2list, 0x2, 0x1);
+		} else {
+			// process 1
+			ret = process_local_list(&rev1list, 0x1, 0x2);
+		}
+		if (ret) {
+			free_commit_list(rev1list);
+			free_commit_list(rev2list);
+			return ret;
+		}
+	}
+	return NULL;
+}
+
+void insert_merge_nodes(struct commit_list *plist,
+			struct commit_list *stop,
+			struct commit *node)
+{
+	struct commit_list *p;
+	for (p=plist; p != stop; p=p->next)
+		commit_list_insert(	common_local_ancestor(node, p->item),
+					&node->merge_nodes);
+}
+
+struct commit *pop_newest_local_commit(	struct commit_list **list,
+					unsigned int mark)
+{
+	struct commit *ret = (*list)->item;
+	struct commit_list *parents = ret->parents;
+	struct commit_list *old = *list;
+	struct commit_list *prev = ret->merge_nodes;
+
+	*list = (*list)->next;
+	free(old);
+
+	/* Loop expects parents to be ordered oldest to newest on local time */
+	while (parents) {
+		struct commit *commit = parents->item;
+		parse_commit(commit);
+		if (!((commit->object.flags & mark) | 
+                       found_on_list(commit, ret->merge_nodes))) {
+			commit->object.flags |= mark;
+			prev = commit->merge_nodes = copy_commit_list(prev);
+			insert_merge_nodes(ret->parents, parents, commit);
+			commit_list_insert(commit, list);
+		}
+		parents = parents->next;
+	}
+	return ret;
+}
Index: commit.h
===================================================================
--- a/commit.h  (mode:100644)
+++ b/commit.h  (mode:100644)
@@ -11,8 +11,9 @@
 
 struct commit {
 	struct object object;
-	unsigned long date;
+	unsigned long date, local_date;
 	struct commit_list *parents;
+	struct commit_list *merge_nodes;
 	struct tree *tree;
 };
 
@@ -36,4 +37,7 @@
 struct commit *pop_most_recent_commit(struct commit_list **list, 
 				      unsigned int mark);
 
+struct commit *pop_newest_local_commit(	struct commit_list **list,
+					unsigned int mark);
+
 #endif /* COMMIT_H */
Index: rev-list.c
===================================================================
--- a/rev-list.c  (mode:100644)
+++ b/rev-list.c  (mode:100644)
@@ -38,7 +38,7 @@
 
 	commit_list_insert(commit, &list);
 	do {
-		struct commit *commit = pop_most_recent_commit(&list, 0x1);
+		struct commit *commit = pop_newest_local_commit(&list, 0x4);
 
 		if (min_age != -1 && (commit->date > min_age))
 			continue;
Index: sha1_file.c
===================================================================
--- a/sha1_file.c  (mode:100644)
+++ b/sha1_file.c  (mode:100644)
@@ -577,6 +577,14 @@
 	return !!find_sha1_file(sha1, &st);
 }
 
+unsigned long sha1_local_date(const unsigned char *sha1)
+{
+	struct stat st;
+	if (find_sha1_file(sha1, &st))
+		return st.st_mtime;
+	return 0;
+}
+
 int index_fd(unsigned char *sha1, int fd, struct stat *st)
 {
 	unsigned long size = st->st_size;

[-- Attachment #3: test-local-rev-list-v1.sh --]
[-- Type: application/octet-stream, Size: 921 bytes --]

#!/bin/bash
die() { echo "death: $*" ; exit 1; }
mkdir R && cd R || die "on mkdir R"
cg-init < /dev/null || die "R init"

touch one ; cg-add one || die "adding Rn-3"
echo "Rn-3" | cg-commit || die "committing Rn-3"

cd .. || die "cd base"
cg-clone R M || die "cloning"

cd M || die "cd M"
touch two; cg-add two || die "adding Mn-1"
echo "Mn-1" | cg-commit || die "committing Mn-1"

cd ../R || die "cd ../R"
touch three; cg-add three || die "adding Rn-2"
echo "Rn-2" | cg-commit || die "committing Rn-2"

cd ../M || die "cd ../M"
touch four; cg-add four || die "adding Mn"
echo "Mn" | cg-commit || die "committing Mn"

cd ../R || die "cd ../R"
touch five; cg-add five || die "adding Rn-1"
echo "Rn-1" | cg-commit || die "committing Rn-1"

sleep 1
cg-branch-add M ../M/.git || die "adding M branch"
echo "Rn" | cg-update M || die "merging M"

sleep 1
cd ../M || die "cd ../M"
cg-update origin || die "fast forwarding to R"

^ permalink raw reply

* Re: [RFD] Ignore rules
From: Junio C Hamano @ 2005-05-14 18:12 UTC (permalink / raw)
  To: Petr Baudis; +Cc: David Greaves, torvalds, GIT Mailing Lists
In-Reply-To: <20050514153027.GN3905@pasky.ji.cz>

>>>>> "PB" == Petr Baudis <pasky@ucw.cz> writes:

PB> Here, I would like more people to speak up, plaese, especially the
PB> authors of other layers over git than Cogito, since I think it'd be
PB> great if we could agree on common ignore rules format and we could just
PB> call the files ".gitignore" instead of ".cgignore", ".jitignore" etc.

Purely off the top of my head, without even regurgitating what
you wrote in the message I am responding to (sorry, I am about
to leave for the day).

 * Two lists, one propagated with merges and another repository
   private one.

 * GIT_DIR/info/ignore is the one propagated with merge but it
   is not a list itself.  It records the name of a file that is
   GIT tracked.  GIT_DIR/ignore is the repository private one.

 * Repository private one and then merge propagated one are read
   in order, one line at a time.  The first hit determines
   whether it is taken or ignored.

 * Each entry in the list is not a shell glob but a regexp.  The
   ignore list rarely changes, so more expressiveness with a bit
   higher learning curve and a bit more typing would not hurt
   much.  The entry is implicitly anchored at the left and
   matched against the path relative to what is recorded in
   GIT_INDEX_FILE (so 'Makefile' matches "Makefile" in
   linux-2.6.git/ but not "fs/Makefile").  The regexp can
   optionally prefixed with a '!' to mean negation.  A line that
   starts with a '#' is a comment.


^ permalink raw reply

* Re: [RFD] Ignore rules
From: David Greaves @ 2005-05-14 17:51 UTC (permalink / raw)
  To: Petr Baudis; +Cc: Junio C Hamano, torvalds, GIT Mailing Lists
In-Reply-To: <20050514153027.GN3905@pasky.ji.cz>

Petr Baudis wrote:

>Here, I would like more people to speak up, plaese, especially the
>authors of other layers over git than Cogito, since I think it'd be
>great if we could agree on common ignore rules format and we could just
>call the files ".gitignore" instead of ".cgignore", ".jitignore" etc.
>
>
>Dear diary, on Sat, May 14, 2005 at 05:13:08PM CEST, I got a letter
>where David Greaves <david@dgreaves.com> told me that...
>  
>
>>I was wondering about supporting _both_ globs and re's
>>right now my ignore file has a # to precede comment lines
>>    
>>
>
>I assume \# will override that?
>  
>
doesn't match /^\w#/ so yes

>>maybe re: precedes regexp lines and unadorned lines are globs.
>>    
>>
>Or maybe even /, which is the common regexp prefix anyway...
>  
>
I thought about it but thought it would look strange since we won't want
a closing /
OTOH, no globs will start with a / since they have to be relative so
maybe a good choice after all.

>To mention it in this mail too, I think leading '!' should do the
>"ignore exclude" - that is, it would override any possible previous
>ignore decisions about the file. E.g. '!*' would throw away all
>previously applied ignore rules.
>  
>
Well, CVS has a lone ! meaning just that.
I wonder if we should simply say that most patterns are 'ignore' patterns.
'!' patterns are 'accept' patterns.
The last seen pattern wins

so given:
*.o
!fre*.o
freddy.o

frog.o is ignored
fred.o is seen
freddy.o is ignored

This means !* (or is that !**) has the same effect as a lone ! in CVS.

>>However the re's provided by regex(7) are too weedy to be worth
>>bothering with.
>>If however, there is a serious plan to go to perl, it may be worth
>>providing for this now in the ignore syntax.
>>
>>Also... you haven't mentioned perl for a while - can you give us an update?
>>I personally think we're making life needlessly unpleasant by sticking
>>with shell.
>>    
>>
>
>If there is still a serious plan, it is much more long-term now, since
>shell turns out to keep doing fine and everything we need, and that all
>reasonably fast.
>
>That said, I think it's fine to use Perl regexps. I think they rule. :-)
>But what do others think? Should we stick with POSIX regexps (I assume
>at least extended instead of basic), or go with Perl regexps?
>  
>
I vote perl re's
You have the power if needed but most of the time it'll be basic regexps.
I think if we have a central 'path' matching .git/ignore then regexps
are needed.
Then if we have them, we may as well allow them.
OTOH: A plethora of .gitignore files with the !negation mechanism may
make globs adequate.

>>Additionally this causes problems with sharing the same exclude file as
>>used by git.
>>However...
>>I really think git's exclude file capability and cogito's are different.
>>Cogito is aiming to provide full-blown SCM capabilities - git isn't
>>    
>>
>
>If we get to agree on some common format, I'm thinking whether it
>wouldn't be actually good to extend the --exclude option to support it.
>How much of an issue would that be? What do others think?
>  
>
I'm not convinced it needs to be extended.
It's trivial to take git-ls-files and filter it's results.
The rest of git will need filtering.

>>I am also concerned that a centralised ignore file is not flexible enough.
>>Certainly limiting if we support globs only.
>>It may be that you want different rules in different trees - someone on
>>lkml mentioned that excludes vary in different parts of the source.
>>Eg .s files may be generally ignored - but not in the asm parts of the tree.
>>    
>>
>
>I imagine it as (ignore rules applied in this order):
>
><default ignore list>:
>
>Some builtin ignore list catching files like *.o, *.a and such.
>  
>
Why builtin?
Why not have a default setup for .git/ignore
The way I'd do it is in cg-init :
[ -f cogito.ignore ] && mv cogito.ignore .git/ignore
[ ! -f .git/ignore ] && cat <<STD_IGNORE > .git/ignore

>Remember that you can throw it away with !* if you don't like it.
>  
>
but it means reading the man pages to find it out whilst you're editing
.git/gitignore
I could never remember what CVS ignored...

>/.git/ignore:
>
>Per-repository ignore list, not version tracked etc; really a local thing.
>  
>
~/.gitignore ?? CVS has it - personal prefs for your editor's strange
numbered backups etc

>/.gitignore
>/**/.gitignore:
>
>(Applied in the order from the project root to the current directory.)
>  
>
>Version tracked ignore list, which concerns the current directory, BUT
>may match pathnames instead of just filenames (but no ..). That is, you
>could do something like
>
>	echo '*.o' >.gitignore
>
>to ignore all the object files in the current directory, and
>
>	echo '**.o' >.gitignore
>
>to also ignore the object files in all the subdirectories.
>  
>
well, is the matching against files or paths?
And do .gitignores affect their sub-tree or just their dir?
And if they're vc'ed then git needs to stop ignoring .files

>
>Opinions?
>  
>

I think the global ignores contain both:
* regexps against the path relative to the project root
* regexps against the filename
* shell globs against the filename
I think the .gitignore's operate on a per-tree basis (so their directory
and lower)
I think .gitignore matching should be against filenames (not paths)

# comments
/regexp
!/inverted regexp
shellglob
!inverted shellglob




Lesson from the CVS manual:
Specifying `-I !' to `cvs import' will import everything, which is
generally what you want to do if you are importing files from a
pristine distribution or any other source which is known to not contain
any extraneous files. However, looking at the rules above you will see
there is a fly in the ointment; if the distribution contains any
`.cvsignore' files, then the patterns from those files will be
processed even if `-I !' is specified. The only workaround is to
remove the `.cvsignore' files in order to do the import. Because this
is awkward, in the future `-I !' might be modified to override
`.cvsignore' files in each directory.





-- 


^ permalink raw reply

* Re: Test scripts naming
From: Junio C Hamano @ 2005-05-14 17:18 UTC (permalink / raw)
  To: Petr Baudis; +Cc: junkio, git
In-Reply-To: <20050514165321.GX3905@pasky.ji.cz>

>>>>> "PB" == Petr Baudis <pasky@ucw.cz> writes:

PB>   I'd propose:
PB> ...
PB> t0500-ls-files.sh       -> t3010-ls-files-killed.sh

Agreed to all of the above.  I will not be online most of today
so if you feel like it, I'd really appreciate it if you do the
renames and documentation yourself without waiting for me.



^ permalink raw reply

* Test scripts naming
From: Petr Baudis @ 2005-05-14 16:53 UTC (permalink / raw)
  To: junkio; +Cc: git

  Hello,

  I think we should do something about the test script names. Currently
it appears almost like the scripts are basically unordered, and the
digit you increment is chosen mostly randomly. Also, the "freeform"
field after the test number is not as informative as it could be. What
are the rules you use for naming the testcases? Could you please
document it in the README?

  I'd propose:

  First digit: "family", e.g. the absolute basics and global stuff (0),
the basic db-side commands (read-tree, write-tree, commit-tree), the
basic working-tree-side commands (checkout-cache, update-cache), the
other basic commands (ls-files), the diff commands, the pull commands,
exporting commands, revision tree commands...

  Second digit: the particular command we are testing

  Third digit: (optionally) the particular switch or group of switches
we are testing

  Freeform part: commandname-details

  How would I rename the current scripts?

t1000-checkout-cache.sh -> t2000-checkout-cache-clash.sh
t1001-checkout-cache.sh -> t2001-checkout-cache-clash.sh
t0200-update-cache.sh   -> t2010-update-cache-badpath.sh
t0400-ls-files.sh       -> t3000-ls-files-others.sh
t0500-ls-files.sh       -> t3010-ls-files-killed.sh

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
C++: an octopus made by nailing extra legs onto a dog. -- Steve Taylor

^ permalink raw reply

* Re: Rename tracking
From: Junio C Hamano @ 2005-05-14 16:36 UTC (permalink / raw)
  To: Petr Baudis; +Cc: torvalds, git
In-Reply-To: <20050514162133.GW3905@pasky.ji.cz>

>>>>> "PB" == Petr Baudis <pasky@ucw.cz> writes:

PB> Well, I'd say that with those renaming patches we are feeling the need
PB> for it?

Again, not me.  What I did (and asked you to do) was to help
_others_ who are interested in rename tracking, not me.  Find
the following message in the archive if you want to know why I
am not in urgent need for rename tracking.

    To:	Linus Torvalds <torvalds@osdl.org>
    Cc:	David Greaves <david@dgreaves.com>, git@vger.kernel.org
    Subject: GIT blame (was Re: Quick command reference)
    From:	Junio C Hamano <junkio@cox.net>
    Date:	Fri, 06 May 2005 02:32:30 -0700
    X-Mailing-List:	git@vger.kernel.org

    >>>>> I == Junio C Hamano <junkio@cox.net> said:

    JCH> Linus, please pull from git-jc.git archive at:
    JCH>     http://members.cox.net/junkio/git-jc.git/

    Since that message I have added a couple more commits there.
    One of the things is a backport of -t (tag) flag to git-ls-files
    from Cogito fork.

    The reason I am writing this message is not because I am excited
    about the backport [*1*], but because I find it quite cool the
    way I found out which commit in Pasky's development line
    introduced the change.  It demonstrates your previous "renames
    does not matter when doing CVS blame" argument actually works.

    Here is what I did: ... (the rest omitted) ...


^ permalink raw reply

* Re: [PATCH] Resurrect diff-tree-helper -R
From: Junio C Hamano @ 2005-05-14 16:27 UTC (permalink / raw)
  To: Petr Baudis; +Cc: Linus Torvalds, git
In-Reply-To: <20050514150356.GK3905@pasky.ji.cz>

>>>>> "PB" == Petr Baudis <pasky@ucw.cz> writes:

Now I understand which discussion I was missing ;-).

PB> For humans I'd say "Mode change" instead of "mode" would be better, and
PB> for machines I still think "@" would be better than "#". "#" can occur
PB> quite naturally in some code snippets or whatever pasted to the commit
PB> message, which is extremely unlikely for "@". What are the advantages
PB> of "#"?

Wait a minute.  Aren't we scanning starting from the first
'---\n'?  Why does what's in commit message matter?

And it is not really "Mode change" anymore.  If you used to have
file there and you replaced it with a symlink, that is 100644 to
120000 "mode change".  I experimented with different things in
where I have "# mode: " there and seriously considered to spell
it "# git:" instead, because that is not really mode and it is
something that means something special to git.  Also I tried to
say just "@. " --- it _was_ confusing to human eye, especially
if you are used to reading diffs.

What I think is that this should not really matter much for
human consumption, because mode change is rare and type change
is even more rare.

PB> I like the rest. That's basically what I've imagined, and
PB> without the arrows it's even better. :-)

Here is what I'd propose for you to do.  (1) Take the patch as
is and commit; (2) Change the definition of git_prefix in diff.c
to "\n@. " and commit; (3) If you already took the test suite,
match t/t2000-diff.sh for the "\n@. " format, and commit.  

It will look something like this. thanks to the leading newline,
the output becomes a bit less confusing (without that blank
line, it really is a disaster for human eyes).

    @. 100644 100755 path0
    --- a/path0
    +++ b/path0
    @@ -1,3 +1,3 @@
     Line 1
     Line 2
    -line 3
    +Line 3

    @. 100755 . path1
    --- a/path1
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -Line 1
    -Line 2
    -line 3


^ permalink raw reply

* Re: Rename tracking
From: Petr Baudis @ 2005-05-14 16:21 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: torvalds, git
In-Reply-To: <7v4qd523p1.fsf@assigned-by-dhcp.cox.net>

Dear diary, on Sat, May 14, 2005 at 06:05:30PM CEST, I got a letter
where Junio C Hamano <junkio@cox.net> told me that...
> >>>>> "PB" == Petr Baudis <pasky@ucw.cz> writes:
> 
> PB> I'll postpone it for another while since there is still some discussion
> PB> about tuning the output.
> 
> What discussion did I miss???

Mainly

From: Petr Baudis <pasky@ucw.cz>
Date: Sat, 14 May 2005 17:03:56 +0200
Subject: Re: [PATCH] Resurrect diff-tree-helper -R
Message-ID: <20050514150356.GK3905@pasky.ji.cz>

> PB> I'm thinking about using "\n---\n\n" in commit message to separate some
> PB> "internal data" like this. cg-log (and web interfaces and other
> PB> toolkits, if we get to agree on something common) could then by default
> PB> hide it. Below it would contain something which we could hopefully embed
> PB> in patches too (actually less work for extracting patches by cg-mkpatch
> PB> or similar tools). What do you think?
> 
> Since I have not been particularly interested in rename tracking
> (because I myself personally have not felt the need for it), I
> do not offhand have much idea worth to offer.  Sorry.

Well, I'd say that with those renaming patches we are feeling the need
for it?

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
C++: an octopus made by nailing extra legs onto a dog. -- Steve Taylor

^ permalink raw reply

* Re: [PATCH] Add --author match to git-rev-list and git-rev-tree.
From: Zack Brown @ 2005-05-14 16:02 UTC (permalink / raw)
  To: Petr Baudis; +Cc: Junio C Hamano, torvalds, git
In-Reply-To: <20050514155257.GR3905@pasky.ji.cz>

On Sat, May 14, 2005 at 05:52:57PM +0200, Petr Baudis wrote:
> Dear diary, on Sat, May 14, 2005 at 05:06:07PM CEST, I got a letter
> where Zack Brown <zbrown@tumblerings.org> told me that...
> > On Sat, May 14, 2005 at 02:50:24AM -0700, Junio C Hamano wrote:
> > > Zack Brown wondered if handling author match at core GIT level
> > > would make cg-log -u go faster (JIT also can use this in jit-log
> > > --author).  Here is a patch to implement it.
> > > 
> > > I considered adding author and committer strings to commit
> > > objects for general use as commit objects are parsed, but I was
> > > unsure about the lifetime rules of the commit objects (nobody
> > > seems to free them in the current code), so refrained from doing
> > > so for the time being.  The code instead re-reads the commit
> > > object when it needs to filter them by the author.
> > 
> > I applied this, but can't figure out the change to make to cg-log in order to
> > actually test it.
> > 
> > - git-cat-file commit $commit | grep -e '^author ' -e '^committer ' | grep -qi "$user" || continue
> > + git-cat-file --author $user commit $commit || continue
> > 
> > sure didn't work.
> 
> You throw that whole thing away and pass the --author parameter directly
> to git-rev-(list|tree).

You mean like this?

Be well,
Zack


Use git-rev-(list|tree) --author to cg-log

Signed-off-by: Zack Brown <zbrown@tumblerings.org>

--- de641904363cd3759f132ee7c0dfaf8a2ee58388/cg-log  (mode:100755)
+++ uncommitted/cg-log  (mode:100755)
@@ -112,12 +112,20 @@
 if [ "$log_end" ]; then
        id1="$(commit-id $log_start)" || exit 1
        id2="$(commit-id $log_end)" || exit 1
-       revls="git-rev-tree $id2 ^$id1"
+       if [ "$user" ]; then
+               revls="git-rev-tree --author $user $id2 ^$id1"
+       else
+               revls="git-rev-tree $id2 ^$id1"
+       fi
        revsort="sort -rn"
        revfmt="git-rev-tree"
 else
        id1="$(commit-id $log_start)" || exit 1
-       revls="git-rev-list $id1"
+       if [ "$user" ]; then
+               revls="git-rev-list --author $user $id1"
+       else
+               revls="git-rev-list $id1"
+       fi
        revsort="cat"
        revfmt="git-rev-list"
 fi
@@ -131,9 +139,6 @@
                parent=$(git-cat-file commit $commit | sed -n '2s/parent //p;2Q')
                [ "$parent" ] && [ "$(git-diff-tree -r $commit $parent "$@")" ] || continue
        fi
-       if [ "$user" ]; then
-               git-cat-file commit $commit | grep -e '^author ' -e '^committer ' | grep -qi "$user" || continue
-       fi
        echo $colheader""commit ${commit%:*} $coldefault;
        git-cat-file commit $commit | \
                while read key rest; do

> 
> -- 
> 				Petr "Pasky" Baudis
> Stuff: http://pasky.or.cz/
> C++: an octopus made by nailing extra legs onto a dog. -- Steve Taylor
> -
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 
Zack Brown

^ permalink raw reply

* Re: Rename tracking
From: Junio C Hamano @ 2005-05-14 16:05 UTC (permalink / raw)
  To: Petr Baudis; +Cc: torvalds, git
In-Reply-To: <20050514151159.GL3905@pasky.ji.cz>

>>>>> "PB" == Petr Baudis <pasky@ucw.cz> writes:

PB> I'll postpone it for another while since there is still some discussion
PB> about tuning the output.

What discussion did I miss???

PB> I'm thinking about using "\n---\n\n" in commit message to separate some
PB> "internal data" like this. cg-log (and web interfaces and other
PB> toolkits, if we get to agree on something common) could then by default
PB> hide it. Below it would contain something which we could hopefully embed
PB> in patches too (actually less work for extracting patches by cg-mkpatch
PB> or similar tools). What do you think?

Since I have not been particularly interested in rename tracking
(because I myself personally have not felt the need for it), I
do not offhand have much idea worth to offer.  Sorry.


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox