* Re: What's in git.git
From: Alexandre Julliard @ 2006-03-05 10:47 UTC (permalink / raw)
To: Martin Langhoff; +Cc: Junio C Hamano, git
In-Reply-To: <46a038f90603050215v7afcbd4crc145e85a4da416a7@mail.gmail.com>
"Martin Langhoff" <martin.langhoff@gmail.com> writes:
> So I should use a combination of both? Hmmm. Worth exploring, can you
> give us a quick guide on getting started with it? (Or where should I
> read? I'm not that good with emacs)...
To get started with the VC backend, make sure vc-git.el is somewhere
on your emacs load-path, and add GIT to the vc-handled-backends
variable; the easiest is with customize, something like
`M-x customize-variable [RET] vc-handled-backends'.
Once you have done that, when you open a file that's under git
control, the vc-git mode should automatically be turned on, and you
should see a "GIT" indicator in the modeline. Then you can use the
standard VC backend commands (the ones that start with the C-x v
prefix). The Emacs VC mode is documented at:
http://www.gnu.org/software/emacs/manual/html_node/Version-Control.html
For the git-status mode, simply do a `M-x load-file [RET] git.el', and
then `M-x git-status'. This will prompt you for the directory to view,
and display a list of modified files. From there you can mark files
and perform actions on group of files, like diff, commit, revert, etc.
There isn't a lot of documentation at this point, but a `C-h m' will
show you the list of key bindings, so you can try them all and see
what happens ;-)
> Oh. Ah. Ok! I'll have to try this! So far, I've had good luck
> following this guide:
>
> http://wiki.gnuarch.org/Process_20_2a_2erej_20files
>
> which is targetted pretty much at dumb emacs users. Like me ;-)
smerge mode is a very simple mode to edit files that contain conflict
markers, in my experience it works pretty well. The nice thing is that
it works directly from the file buffer, so you don't need to jump back
and forth between file and diff.
--
Alexandre Julliard
julliard@winehq.org
^ permalink raw reply
* [PATCH] git-blame: Use the same tests for git-blame as for git-annotate
From: Fredrik Kuivinen @ 2006-03-05 11:13 UTC (permalink / raw)
To: git; +Cc: junkio
Signed-off-by: Fredrik Kuivinen <freku045@student.liu.se>
---
t/annotate-tests.sh | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++
t/t8001-annotate.sh | 85 +-------------------------------------------------
t/t8002-blame.sh | 9 +++++
3 files changed, 97 insertions(+), 83 deletions(-)
create mode 100644 t/annotate-tests.sh
create mode 100755 t/t8002-blame.sh
06b0e500a5202899dcfd037cf78ee4a982da46b4
diff --git a/t/annotate-tests.sh b/t/annotate-tests.sh
new file mode 100644
index 0000000..54a4dfb
--- /dev/null
+++ b/t/annotate-tests.sh
@@ -0,0 +1,86 @@
+# This file isn't used as a test script directly, instead it is
+# sourced from t8001-annotate.sh and t8001-blame.sh.
+
+test_expect_success \
+ 'prepare reference tree' \
+ 'echo "1A quick brown fox jumps over the" >file &&
+ echo "lazy dog" >>file &&
+ git add file
+ GIT_AUTHOR_NAME="A" git commit -a -m "Initial."'
+
+test_expect_success \
+ 'check all lines blamed on A' \
+ '[ $(git annotate file | awk "{print \$3}" | grep -c "A") == 2 ]'
+
+test_expect_success \
+ 'Setup new lines blamed on B' \
+ 'echo "2A quick brown fox jumps over the" >>file &&
+ echo "lazy dog" >> file &&
+ GIT_AUTHOR_NAME="B" git commit -a -m "Second."'
+
+test_expect_success \
+ 'Two lines blamed on A' \
+ '[ $($PROG file | awk "{print \$3}" | grep -c "A") == 2 ]'
+
+test_expect_success \
+ 'Two lines blamed on B' \
+ '[ $($PROG file | awk "{print \$3}" | grep -c "B") == 2 ]'
+
+test_expect_success \
+ 'merge-setup part 1' \
+ 'git checkout -b branch1 master &&
+ echo "3A slow green fox jumps into the" >> file &&
+ echo "well." >> file &&
+ GIT_AUTHOR_NAME="B1" git commit -a -m "Branch1-1"'
+
+test_expect_success \
+ 'Two lines blamed on A' \
+ '[ $($PROG file | awk "{print \$3}" | grep -c "^A$") == 2 ]'
+
+test_expect_success \
+ 'Two lines blamed on B' \
+ '[ $($PROG file | awk "{print \$3}" | grep -c "^B$") == 2 ]'
+
+test_expect_success \
+ 'Two lines blamed on B1' \
+ '[ $($PROG file | awk "{print \$3}" | grep -c "^B1$") == 2 ]'
+
+test_expect_success \
+ 'merge-setup part 2' \
+ 'git checkout -b branch2 master &&
+ sed -e "s/2A quick brown/4A quick brown lazy dog/" < file > file.new &&
+ mv file.new file &&
+ GIT_AUTHOR_NAME="B2" git commit -a -m "Branch2-1"'
+
+test_expect_success \
+ 'Two lines blamed on A' \
+ '[ $($PROG file | awk "{print \$3}" | grep -c "^A$") == 2 ]'
+
+test_expect_success \
+ 'One line blamed on B' \
+ '[ $($PROG file | awk "{print \$3}" | grep -c "^B$") == 1 ]'
+
+test_expect_success \
+ 'One line blamed on B2' \
+ '[ $($PROG file | awk "{print \$3}" | grep -c "^B2$") == 1 ]'
+
+
+test_expect_success \
+ 'merge-setup part 3' \
+ 'git pull . branch1'
+
+test_expect_success \
+ 'Two lines blamed on A' \
+ '[ $($PROG file | awk "{print \$3}" | grep -c "^A$") == 2 ]'
+
+test_expect_success \
+ 'One line blamed on B' \
+ '[ $($PROG file | awk "{print \$3}" | grep -c "^B$") == 1 ]'
+
+test_expect_success \
+ 'Two lines blamed on B1' \
+ '[ $($PROG file | awk "{print \$3}" | grep -c "^B1$") == 2 ]'
+
+test_expect_success \
+ 'One line blamed on B2' \
+ '[ $($PROG file | awk "{print \$3}" | grep -c "^B2$") == 1 ]'
diff --git a/t/t8001-annotate.sh b/t/t8001-annotate.sh
index 172908a..9e5a04b 100755
--- a/t/t8001-annotate.sh
+++ b/t/t8001-annotate.sh
@@ -3,88 +3,7 @@
test_description='git-annotate'
. ./test-lib.sh
-test_expect_success \
- 'prepare reference tree' \
- 'echo "1A quick brown fox jumps over the" >file &&
- echo "lazy dog" >>file &&
- git add file
- GIT_AUTHOR_NAME="A" git commit -a -m "Initial."'
-
-test_expect_success \
- 'check all lines blamed on A' \
- '[ $(git annotate file | awk "{print \$3}" | grep -c "A") == 2 ]'
-
-test_expect_success \
- 'Setup new lines blamed on B' \
- 'echo "2A quick brown fox jumps over the" >>file &&
- echo "lazy dog" >> file &&
- GIT_AUTHOR_NAME="B" git commit -a -m "Second."'
-
-test_expect_success \
- 'Two lines blamed on A' \
- '[ $(git annotate file | awk "{print \$3}" | grep -c "A") == 2 ]'
-
-test_expect_success \
- 'Two lines blamed on B' \
- '[ $(git annotate file | awk "{print \$3}" | grep -c "B") == 2 ]'
-
-test_expect_success \
- 'merge-setup part 1' \
- 'git checkout -b branch1 master &&
- echo "3A slow green fox jumps into the" >> file &&
- echo "well." >> file &&
- GIT_AUTHOR_NAME="B1" git commit -a -m "Branch1-1"'
-
-test_expect_success \
- 'Two lines blamed on A' \
- '[ $(git annotate file | awk "{print \$3}" | grep -c "^A$") == 2 ]'
-
-test_expect_success \
- 'Two lines blamed on B' \
- '[ $(git annotate file | awk "{print \$3}" | grep -c "^B$") == 2 ]'
-
-test_expect_success \
- 'Two lines blamed on B1' \
- '[ $(git annotate file | awk "{print \$3}" | grep -c "^B1$") == 2 ]'
-
-test_expect_success \
- 'merge-setup part 2' \
- 'git checkout -b branch2 master &&
- sed -e "s/2A quick brown/4A quick brown lazy dog/" < file > file.new &&
- mv file.new file &&
- GIT_AUTHOR_NAME="B2" git commit -a -m "Branch2-1"'
-
-test_expect_success \
- 'Two lines blamed on A' \
- '[ $(git annotate file | awk "{print \$3}" | grep -c "^A$") == 2 ]'
-
-test_expect_success \
- 'One line blamed on B' \
- '[ $(git annotate file | awk "{print \$3}" | grep -c "^B$") == 1 ]'
-
-test_expect_success \
- 'One line blamed on B2' \
- '[ $(git annotate file | awk "{print \$3}" | grep -c "^B2$") == 1 ]'
-
-
-test_expect_success \
- 'merge-setup part 3' \
- 'git pull . branch1'
-
-test_expect_success \
- 'Two lines blamed on A' \
- '[ $(git annotate file | awk "{print \$3}" | grep -c "^A$") == 2 ]'
-
-test_expect_success \
- 'One line blamed on B' \
- '[ $(git annotate file | awk "{print \$3}" | grep -c "^B$") == 1 ]'
-
-test_expect_success \
- 'Two lines blamed on B1' \
- '[ $(git annotate file | awk "{print \$3}" | grep -c "^B1$") == 2 ]'
-
-test_expect_success \
- 'One line blamed on B2' \
- '[ $(git annotate file | awk "{print \$3}" | grep -c "^B2$") == 1 ]'
+PROG='git annotate'
+source ../annotate-tests.sh
test_done
diff --git a/t/t8002-blame.sh b/t/t8002-blame.sh
new file mode 100755
index 0000000..1036c54
--- /dev/null
+++ b/t/t8002-blame.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+test_description='git-blame'
+. ./test-lib.sh
+
+PROG='git blame -c'
+source ../annotate-tests.sh
+
+test_done
--
1.2.4.g4644-dirty
^ permalink raw reply related
* [PATCH] git-blame: Make the output human readable
From: Fredrik Kuivinen @ 2006-03-05 11:03 UTC (permalink / raw)
To: git; +Cc: junkio
The default output mode is slightly different from git-annotate's.
However, git-annotate's output mode can be obtained by using the
'-c' flag.
Signed-off-by: Fredrik Kuivinen <freku045@student.liu.se>
---
Makefile | 4 ++
blame.c | 164 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
2 files changed, 149 insertions(+), 19 deletions(-)
3459b7c5032d1462d5857cf6afc2d3e3ef61b93b
diff --git a/Makefile b/Makefile
index b6d8804..eb1887d 100644
--- a/Makefile
+++ b/Makefile
@@ -534,6 +534,10 @@ git-rev-list$X: rev-list.o $(LIB_FILE)
$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
$(LIBS) $(OPENSSL_LIBSSL)
+git-blame$X: blame.o $(LIB_FILE)
+ $(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
+ $(LIBS) -lm
+
init-db.o: init-db.c
$(CC) -c $(ALL_CFLAGS) \
-DDEFAULT_GIT_TEMPLATE_DIR='"$(template_dir_SQ)"' $*.c
diff --git a/blame.c b/blame.c
index 7308c36..6dccae5 100644
--- a/blame.c
+++ b/blame.c
@@ -5,6 +5,7 @@
#include <assert.h>
#include <time.h>
#include <sys/time.h>
+#include <math.h>
#include "cache.h"
#include "refs.h"
@@ -17,8 +18,15 @@
#define DEBUG 0
-struct commit **blame_lines;
-int num_blame_lines;
+static const char blame_usage[] = "[-c] [-l] [--] file [commit]\n"
+ " -c, --compability Use the same output mode as git-annotate (Default: off)\n"
+ " -l, --long Show long commit SHA1 (Default: off)\n"
+ " -h, --help This message";
+
+static struct commit **blame_lines;
+static int num_blame_lines;
+static char* blame_contents;
+static int blame_len;
struct util_info {
int *line_map;
@@ -388,9 +396,8 @@ static void init_first_commit(struct com
alloc_line_map(commit);
util = commit->object.util;
- num_blame_lines = util->num_lines;
- for (i = 0; i < num_blame_lines; i++)
+ for (i = 0; i < util->num_lines; i++)
util->line_map[i] = i;
}
@@ -412,6 +419,9 @@ static void process_commits(struct rev_i
util = commit->object.util;
num_blame_lines = util->num_lines;
blame_lines = xmalloc(sizeof(struct commit *) * num_blame_lines);
+ blame_contents = util->buf;
+ blame_len = util->size;
+
for (i = 0; i < num_blame_lines; i++)
blame_lines[i] = NULL;
@@ -499,32 +509,128 @@ static void process_commits(struct rev_i
} while ((commit = get_revision(rev)) != NULL);
}
+struct commit_info
+{
+ char* author;
+ char* author_mail;
+ unsigned long author_time;
+ char* author_tz;
+};
+
+static void get_commit_info(struct commit* commit, struct commit_info* ret)
+{
+ int len;
+ char* tmp;
+ static char author_buf[1024];
+
+ tmp = strstr(commit->buffer, "\nauthor ") + 8;
+ len = index(tmp, '\n') - tmp;
+ ret->author = author_buf;
+ memcpy(ret->author, tmp, len);
+
+ tmp = ret->author;
+ tmp += len;
+ *tmp = 0;
+ while(*tmp != ' ')
+ tmp--;
+ ret->author_tz = tmp+1;
+
+ *tmp = 0;
+ while(*tmp != ' ')
+ tmp--;
+ ret->author_time = strtoul(tmp, NULL, 10);
+
+ *tmp = 0;
+ while(*tmp != ' ')
+ tmp--;
+ ret->author_mail = tmp + 1;
+
+ *tmp = 0;
+}
+
+char* format_time(unsigned long time, const char* tz)
+{
+ static char time_buf[128];
+ time_t t = time;
+
+ strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S ", gmtime(&t));
+ strcat(time_buf, tz);
+ return time_buf;
+}
+
int main(int argc, const char **argv)
{
int i;
struct commit *initial = NULL;
unsigned char sha1[20];
- const char* filename;
+
+ const char *filename = NULL, *commit = NULL;
+ char filename_buf[256];
+ int sha1_len = 8;
+ int compability = 0;
+ int options = 1;
+
int num_args;
const char* args[10];
struct rev_info rev;
- setup_git_directory();
-
- if (argc != 3)
- die("Usage: blame commit-ish file");
+ struct commit_info ci;
+ const char *buf;
+ int max_digits;
+
+ const char* prefix = setup_git_directory();
+
+ for(i = 1; i < argc; i++) {
+ if(options) {
+ if(!strcmp(argv[i], "-h") ||
+ !strcmp(argv[i], "--help"))
+ usage(blame_usage);
+ else if(!strcmp(argv[i], "-l") ||
+ !strcmp(argv[i], "--long")) {
+ sha1_len = 20;
+ continue;
+ } else if(!strcmp(argv[i], "-c") ||
+ !strcmp(argv[i], "--compability")) {
+ compability = 1;
+ continue;
+ } else if(!strcmp(argv[i], "--")) {
+ options = 0;
+ continue;
+ } else if(argv[i][0] == '-')
+ usage(blame_usage);
+ else
+ options = 0;
+ }
+ if(!options) {
+ if(!filename)
+ filename = argv[i];
+ else if(!commit)
+ commit = argv[i];
+ else
+ usage(blame_usage);
+ }
+ }
- filename = argv[2];
+ if(!filename)
+ usage(blame_usage);
+ if(!commit)
+ commit = "HEAD";
+
+ if(prefix)
+ sprintf(filename_buf, "%s%s", prefix, filename);
+ else
+ strcpy(filename_buf, filename);
+ filename = filename_buf;
{
- struct commit* commit;
- if (get_sha1(argv[1], sha1))
- die("get_sha1 failed");
- commit = lookup_commit_reference(sha1);
+ struct commit* c;
+ if (get_sha1(commit, sha1))
+ die("get_sha1 failed, commit '%s' not found", commit);
+ c = lookup_commit_reference(sha1);
- if (fill_util_info(commit, filename)) {
- printf("%s not found in %s\n", filename, argv[1]);
+ if (fill_util_info(c, filename)) {
+ printf("%s not found in %s\n", filename, commit);
return 1;
}
}
@@ -533,7 +639,7 @@ int main(int argc, const char **argv)
args[num_args++] = NULL;
args[num_args++] = "--topo-order";
args[num_args++] = "--remove-empty";
- args[num_args++] = argv[1];
+ args[num_args++] = commit;
args[num_args++] = "--";
args[num_args++] = filename;
args[num_args] = NULL;
@@ -542,13 +648,33 @@ int main(int argc, const char **argv)
prepare_revision_walk(&rev);
process_commits(&rev, filename, &initial);
+ buf = blame_contents;
+ max_digits = 1 + log(num_blame_lines+1)/log(10);
for (i = 0; i < num_blame_lines; i++) {
struct commit *c = blame_lines[i];
if (!c)
c = initial;
- printf("%d %.8s\n", i, sha1_to_hex(c->object.sha1));
-// printf("%d %s\n", i, find_unique_abbrev(blame_lines[i]->object.sha1, 6));
+ get_commit_info(c, &ci);
+ fwrite(sha1_to_hex(c->object.sha1), sha1_len, 1, stdout);
+ if(compability)
+ printf("\t(%10s\t%10s\t%d)", ci.author,
+ format_time(ci.author_time, ci.author_tz), i+1);
+ else
+ printf(" (%-15.15s %10s %*d) ", ci.author,
+ format_time(ci.author_time, ci.author_tz),
+ max_digits, i+1);
+
+ if(i == num_blame_lines - 1) {
+ fwrite(buf, blame_len - (buf - blame_contents),
+ 1, stdout);
+ if(blame_contents[blame_len-1] != '\n')
+ putc('\n', stdout);
+ } else {
+ char* next_buf = index(buf, '\n') + 1;
+ fwrite(buf, next_buf - buf, 1, stdout);
+ buf = next_buf;
+ }
}
if (DEBUG) {
--
1.2.4.g4644-dirty
^ permalink raw reply related
* Re: What's in git.git
From: Martin Langhoff @ 2006-03-05 10:15 UTC (permalink / raw)
To: Alexandre Julliard; +Cc: Junio C Hamano, git
In-Reply-To: <87irqtjjr1.fsf@wine.dyndns.org>
On 3/5/06, Alexandre Julliard <julliard@winehq.org> wrote:
> You can use both. The VC backend is a per-file mode, that's handy when
> you are editing a file and want a quick diff/revert/commit of just
> that file; the commands are executed directly from the buffer
> containing the file. When making bigger changes, you should use the
> git-status mode (the one in git.el), which is a tree browser that
> gives you a view of the whole project.
So I should use a combination of both? Hmmm. Worth exploring, can you
give us a quick guide on getting started with it? (Or where should I
read? I'm not that good with emacs)...
> > Can we get a new merge conflict mode that generates .rej files? Emacs
> > is superb at dealing with conflicts formatted that way. OTOH, it may
> > be able to deal smartly with diff3-style conflicts if it knows how to
> > talk with the VC backend -- I think the cvs mode can do that.
>
> What emacs mode do you use to resolve conflicts? From the git-status
> buffer, if you edit a file with 'f' it will automatically turn on
> smerge mode if there are conflicts, or you can edit it in ediff merge
> mode with 'd E' like under pcl-cvs. Is that what you mean?
Oh. Ah. Ok! I'll have to try this! So far, I've had good luck
following this guide:
http://wiki.gnuarch.org/Process_20_2a_2erej_20files
which is targetted pretty much at dumb emacs users. Like me ;-)
martin
^ permalink raw reply
* Re: Managing topic branches
From: Junio C Hamano @ 2006-03-05 10:14 UTC (permalink / raw)
To: Martin Langhoff; +Cc: git
In-Reply-To: <46a038f90603050135j41eaf935kd48ab68212218836@mail.gmail.com>
"Martin Langhoff" <martin.langhoff@gmail.com> writes:
> In any case, this was perhaps based on a misunderstanding/error on my
> side. To start off, I didn't understand how you were managing next.
No nononononono nooooo.
If I sounded like you were the guilty party I apologize. I did
not mean it that way.
It was my mistake. I encouraged people to experiment and build
upon "next". It was just the way I pulled the stuff in was bad.
^ permalink raw reply
* [PATCH] cvsserver: updated documentation
From: Martin Langhoff @ 2006-03-05 10:11 UTC (permalink / raw)
To: git, junkio; +Cc: Martin Langhoff
... and stripped trailing whitespace to appease the Gods...
Signed-off-by: Martin Langhoff <martin@catalyst.net.nz>
---
Documentation/git-cvsserver.txt | 87 +++++++++++++++++++++++++++------------
1 files changed, 61 insertions(+), 26 deletions(-)
a67387be3b0dd572f78da9befe27303b20e9cbf1
diff --git a/Documentation/git-cvsserver.txt b/Documentation/git-cvsserver.txt
index 19c9c51..4dc13c3 100644
--- a/Documentation/git-cvsserver.txt
+++ b/Documentation/git-cvsserver.txt
@@ -5,14 +5,12 @@ NAME
----
git-cvsserver - A CVS server emulator for git
-
SYNOPSIS
--------
[verse]
export CVS_SERVER=git-cvsserver
'cvs' -d :ext:user@server/path/repo.git co <HEAD_name>
-
DESCRIPTION
-----------
@@ -27,48 +25,85 @@ plugin. Most functionality works fine wi
LIMITATIONS
-----------
-Currently gitcvs only works over ssh connections.
+Currently cvsserver works over SSH connections for read/write clients, and
+over pserver for anonymous CVS access.
+
+CVS clients cannot tag, branch or perform GIT merges.
INSTALLATION
------------
-1. Put server.pl somewhere useful on the same machine that is hosting your git repos
+
+1. If you are going to offer anonymous CVS access via pserver, add a line in
+ /etc/inetd.conf like
+
+ cvspserver stream tcp nowait nobody git-cvsserver pserver
+
+ Note: In some cases, you need to pass the 'pserver' argument twice for
+ git-cvsserver to see it. So the line would look like
+
+ cvspserver stream tcp nowait nobody git-cvsserver pserver pserver
+
+ No special setup is needed for SSH access, other than having GIT tools
+ in the PATH. If you have clients that do not accept the CVS_SERVER
+ env variable, you can rename git-cvsserver to cvs.
2. For each repo that you want accessible from CVS you need to edit config in
the repo and add the following section.
[gitcvs]
enabled=1
+ # optional for debugging
logfile=/path/to/logfile
- n.b. you need to ensure each user that is going to invoke server.pl has
- write access to the log file.
+ Note: you need to ensure each user that is going to invoke git-cvsserver has
+ write access to the log file and to the git repository. When offering anon
+ access via pserver, this means that the nobody user should have write access
+ to at least the sqlite database at the root of the repository.
+
+3. On the client machine you need to set the following variables.
+ CVSROOT should be set as per normal, but the directory should point at the
+ appropriate git repo. For example:
+
+ For SSH access, CVS_SERVER should be set to git-cvsserver
+
+ Example:
+
+ export CVSROOT=:ext:user@server:/var/git/project.git
+ export CVS_SERVER=git-cvsserver
+
+4. For SSH clients that will make commits, make sure their .bashrc file
+ sets the GIT_AUTHOR and GIT_COMMITTER variables.
+
+5. Clients should now be able to check out the project. Use the CVS 'module'
+ name to indicate what GIT 'head' you want to check out. Example:
-5. On each client machine you need to set the following variables.
- CVSROOT should be set as per normal, but the directory should point at the
- appropriate git repo.
- CVS_SERVER should be set to the server.pl script that has been put on the
- remote machine.
-
-6. Clients should now be able to check out modules (where modules are the names
- of branches in git).
- $ cvs co -d mylocaldir master
+ cvs co -d project-master master
Eclipse CVS Client Notes
------------------------
To get a checkout with the Eclipse CVS client:
-1. Create a new project from CVS checkout, giving it repository and module
-2. Context Menu->Team->Share Project...
-3. Enter the repository and module information again and click Finish
-4. The Synchronize view appears. Untick "launch commit wizard" to avoid
-committing the .project file, and select HEAD as the tag to synchronize to.
-Update all incoming changes.
-
-Note that most versions of Eclipse ignore CVS_SERVER (which you can set in
-the Preferences->Team->CVS->ExtConnection pane), so you may have to
-rename, alias or symlink git-cvsserver to 'cvs' on the server.
+1. Select "Create a new project -> From CVS checkout"
+2. Create a new location. See the notes below for details on how to choose the
+ right protocol.
+3. Browse the 'modules' available. It will give you a list of the heads in
+ the repository. You will not be able to browse the tree from there. Only
+ the heads.
+4. Pick 'HEAD' when it asks what branch/tag to check out. Untick the
+ "launch commit wizard" to avoid committing the .project file.
+
+Protocol notes: If you are using anonymous acces via pserver, just select that.
+Those using SSH access should choose the 'ext' protocol, and configure 'ext'
+access on the Preferences->Team->CVS->ExtConnection pane. Set CVS_SERVER to
+'git-cvsserver'. Not that password support is not good when using 'ext',
+you will definitely want to have SSH keys setup.
+
+Alternatively, you can just use the non-standard extssh protocol that Eclipse
+offer. In that case CVS_SERVER is ignored, and you will have to replace
+the cvs utility on the server with git-cvsserver or manipulate your .bashrc
+so that calling 'cvs' effectively calls git-cvsserver.
Clients known to work
---------------------
@@ -106,7 +141,7 @@ Authors: Martyn Smith <martyn@catalys
Documentation
--------------
-Documentation by Martyn Smith <martyn@catalyst.net.nz> and Martin Langhoff <martin@catalyst.net.nz>Matthias Urlichs <smurf@smurf.noris.de>.
+Documentation by Martyn Smith <martyn@catalyst.net.nz> and Martin Langhoff <martin@catalyst.net.nz> Matthias Urlichs <smurf@smurf.noris.de>.
GIT
---
--
1.2.4.g0a60
^ permalink raw reply related
* Re: What's in git.git
From: Junio C Hamano @ 2006-03-05 10:10 UTC (permalink / raw)
To: Martin Langhoff; +Cc: Junio C Hamano, git
In-Reply-To: <46a038f90603050121u6bccbb71ve78de69ae45b96ad@mail.gmail.com>
"Martin Langhoff" <martin.langhoff@gmail.com> writes:
> I'm somewhat confused by the fact that there are two emacs modes, both
> by Alexandre. Which one should I use? Also -- the killer app for
> emacs+git would be to leverage the great patch-editing mode in emacs.
They are different styles. I've been in VC camp but my
understanding is pcl-cvs style integration is closer to
whole-tree than VC which is more per-file. I still haven't
adjusted to pcl-cvs style yet..
> (of course, if xxdiff and others can help, that'd be cool too, but
> currently they seem strangely unable to deal with files with diff3
> conflict markers.)
I had pleasant experiences with "xxdiff -U".
^ permalink raw reply
* Re: What's in git.git
From: Alexandre Julliard @ 2006-03-05 9:58 UTC (permalink / raw)
To: Martin Langhoff; +Cc: Junio C Hamano, git
In-Reply-To: <46a038f90603050121u6bccbb71ve78de69ae45b96ad@mail.gmail.com>
"Martin Langhoff" <martin.langhoff@gmail.com> writes:
> I'm somewhat confused by the fact that there are two emacs modes, both
> by Alexandre. Which one should I use? Also -- the killer app for
> emacs+git would be to leverage the great patch-editing mode in emacs.
You can use both. The VC backend is a per-file mode, that's handy when
you are editing a file and want a quick diff/revert/commit of just
that file; the commands are executed directly from the buffer
containing the file. When making bigger changes, you should use the
git-status mode (the one in git.el), which is a tree browser that
gives you a view of the whole project.
> Can we get a new merge conflict mode that generates .rej files? Emacs
> is superb at dealing with conflicts formatted that way. OTOH, it may
> be able to deal smartly with diff3-style conflicts if it knows how to
> talk with the VC backend -- I think the cvs mode can do that.
What emacs mode do you use to resolve conflicts? From the git-status
buffer, if you edit a file with 'f' it will automatically turn on
smerge mode if there are conflicts, or you can edit it in ediff merge
mode with 'd E' like under pcl-cvs. Is that what you mean?
--
Alexandre Julliard
julliard@winehq.org
^ permalink raw reply
* [PATCH 3/3] Documentation/git-cvsserver.txt: Fix list numbering.
From: Mark Wooding @ 2006-03-05 9:36 UTC (permalink / raw)
To: git
In-Reply-To: <20060305093351.26650.84677.stgit@metalzone.distorted.org.uk>
From: Mark Wooding <mdw@distorted.org.uk>
Asciidoc complains about the bogus list item numbers in the installation
instructions. Fix them.
Signed-off-by: Mark Wooding <mdw@distorted.org.uk>
---
Documentation/git-cvsserver.txt | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/Documentation/git-cvsserver.txt b/Documentation/git-cvsserver.txt
index 19c9c51..0c4948d 100644
--- a/Documentation/git-cvsserver.txt
+++ b/Documentation/git-cvsserver.txt
@@ -44,13 +44,13 @@ INSTALLATION
n.b. you need to ensure each user that is going to invoke server.pl has
write access to the log file.
-5. On each client machine you need to set the following variables.
+3. On each client machine you need to set the following variables.
CVSROOT should be set as per normal, but the directory should point at the
appropriate git repo.
CVS_SERVER should be set to the server.pl script that has been put on the
remote machine.
-6. Clients should now be able to check out modules (where modules are the names
+4. Clients should now be able to check out modules (where modules are the names
of branches in git).
$ cvs co -d mylocaldir master
^ permalink raw reply related
* [PATCH 2/3] Documentation/Makefile: Some `git-*.txt' files aren't manpages.
From: Mark Wooding @ 2006-03-05 9:36 UTC (permalink / raw)
To: git
In-Reply-To: <20060305093351.26650.84677.stgit@metalzone.distorted.org.uk>
From: Mark Wooding <mdw@distorted.org.uk>
In particular, git-tools.txt isn't a manpage, and my Asciidoc gets upset
by it. The simplest fix is to Remove articles from the list of manpages
the Makefile.
Signed-off-by: Mark Wooding <mdw@distorted.org.uk>
---
Documentation/Makefile | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/Documentation/Makefile b/Documentation/Makefile
index a3bca86..f4cbf7e 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -1,4 +1,7 @@
-MAN1_TXT=$(wildcard git-*.txt) gitk.txt
+MAN1_TXT= \
+ $(filter-out $(addsuffix .txt, $(ARTICLES) $(SP_ARTICLES)), \
+ $(wildcard git-*.txt)) \
+ gitk.txt
MAN7_TXT=git.txt
DOC_HTML=$(patsubst %.txt,%.html,$(MAN1_TXT) $(MAN7_TXT))
@@ -11,6 +14,7 @@ ARTICLES += howto-index
ARTICLES += repository-layout
ARTICLES += hooks
ARTICLES += everyday
+ARTICLES += git-tools
# with their own formatting rules.
SP_ARTICLES = glossary howto/revert-branch-rebase
^ permalink raw reply related
* [PATCH 0/3] Build fixes for v1.2.4-gc9e9f1a
From: Mark Wooding @ 2006-03-05 9:33 UTC (permalink / raw)
To: git
The master branch, as of c9e9f1ad8aae4bd49791d53cc0cd501120884850,
doesn't build cleanly for me. There's a warning about git.c, warnings
about Documentation/git-cvsserver.txt, and an abject failure to process
Documentation/git-tools.txt.
The following patches fix these problems, at least for me.
For reference, I'm running
* gcc (GCC) 4.0.3 20060212 (prerelease) (Debian 4.0.2-9)
* asciidoc 7.0.2
-- [mdw]
^ permalink raw reply
* [PATCH 1/3] git.c: Kill type mismatch warning.
From: Mark Wooding @ 2006-03-05 9:36 UTC (permalink / raw)
To: git
In-Reply-To: <20060305093351.26650.84677.stgit@metalzone.distorted.org.uk>
From: Mark Wooding <mdw@distorted.org.uk>
GCC objects when you pass a `char **' where a `const char **' is wanted.
The cast shuts the compiler up, and does the right thing generally.
Signed-off-by: Mark Wooding <mdw@distorted.org.uk>
---
Unfortunately, the warning is fair enough. I can pass a `T' where
someone was expecting a `const T', but that would mean that the callee
was expecting a `char *const *'.
---
git.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/git.c b/git.c
index a547dbd..69df070 100644
--- a/git.c
+++ b/git.c
@@ -261,7 +261,7 @@ static int cmd_log(int argc, char **argv
int show_parents = 0;
const char *commit_prefix = "commit ";
- argc = setup_revisions(argc, argv, &rev, "HEAD");
+ argc = setup_revisions(argc, (const char **)argv, &rev, "HEAD");
while (1 < argc) {
char *arg = argv[1];
if (!strncmp(arg, "--pretty", 8)) {
^ permalink raw reply related
* Re: Managing topic branches
From: Martin Langhoff @ 2006-03-05 9:35 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vzmk5lkmo.fsf@assigned-by-dhcp.cox.net>
On 3/5/06, Junio C Hamano <junkio@cox.net> wrote:
> I could have done without the "questionable octopus leg", but I
> did so that when Martin pulled my "next" into his cvsserver
...
> The moral of the story is not to try to be nice to others
> without thinking about its concequences ;-). I should have just
> done without the "questionable octopus leg", and asked Martin to
> discard and rebase his tip of the development to my "next" after
> this merge.
No good deed goes unpunished as they say ;-)
In any case, this was perhaps based on a misunderstanding/error on my
side. To start off, I didn't understand how you were managing next.
I assumed next would be a 'rewind often' branch, a volatile thing that
I shouldn't build upon. But as I was in the awkward situation of
depending on something in next, I had to, and didn't think of the
consequences. As the branch I published for you to pull was based on
next, which meant you couldn't merge my stuff into master.
So it was a thinko on my side. I just though -- damn, I'll have to
work based on next, with the downside of having to be alert for
rewinds. Didn't think of the implications for you.
It's sorted now, but at great pains for you. I guess all I can suggest
is to put something in the name of the branch that means both "rewinds
often" and "don't base real work on this". I guess that would be
anything but master/maint, but the rules around pu are sometimes
tricky too (rewinds often, but some people have no option but to build
against it, unless you are treating it same as you treat next).
Anyway -- sorry to have caused so much trouble. My work "pending" is
at the most a patch or two, easy to extract and reapply. If something
like this comes up again, just do whatever is easiest and tell me to
rewind/rebase/cherrypick at my end.
cheers,
martin
^ permalink raw reply
* Re: What's in git.git
From: Martin Langhoff @ 2006-03-05 9:21 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vacc5jza6.fsf@assigned-by-dhcp.cox.net>
On 3/5/06, Junio C Hamano <junkio@cox.net> wrote:
> - Emacs interface (Alexandre Julliard)
> contrib/emacs: Add an Emacs VC backend.
> git.el: Added customize support for all parameters.
> git.el: Added support for Signed-off-by.
> git.el: Automatically update .gitignore status.
> git.el: Portability fixes for XEmacs and Emacs CVS.
> git.el: Set default directory before running the status mode setup hooks.
I'm somewhat confused by the fact that there are two emacs modes, both
by Alexandre. Which one should I use? Also -- the killer app for
emacs+git would be to leverage the great patch-editing mode in emacs.
Can we get a new merge conflict mode that generates .rej files? Emacs
is superb at dealing with conflicts formatted that way. OTOH, it may
be able to deal smartly with diff3-style conflicts if it knows how to
talk with the VC backend -- I think the cvs mode can do that.
Linus has mentioned several times that it is more important to have
well oiled tools to deal with conflicts when they happen -- easy
visualization of what the different versions were, commit msgs,
highlight characters that don't match in a line that looks the same at
first glance, etc -- than to try and magically resolve conflicts. I'm
in violent agreement, and keen on seeing the emacs vc stuff fill that
gap.
(of course, if xxdiff and others can help, that'd be cool too, but
currently they seem strangely unable to deal with files with diff3
conflict markers.)
> - git-cvsserver updates (Martin Langhoff)
Wohoo! This needs testers -- give it a whirl, please! BTW, the
workarounds for Eclipse mentioned in the doco are no longer needed.
Still, you do want to give Documentation/git-cvsserver.txt a quick
read.
cheers,
martin
^ permalink raw reply
* Re: [PATCH] Add --temp and --stage=all options to checkout-index.
From: Junio C Hamano @ 2006-03-05 8:55 UTC (permalink / raw)
To: Shawn Pearce; +Cc: git
In-Reply-To: <20060305082415.GD24437@spearce.org>
Shawn Pearce <spearce@spearce.org> writes:
> This replaces my prior patch. It looks a heck of a lot cleaner too
> due to less indentation changes. :-)
Much nicer. Will put in "next" for wider exposure.
^ permalink raw reply
* Re: [PATCH] Add --temp and --stage=all options to checkout-index.
From: Shawn Pearce @ 2006-03-05 8:24 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vlkvpihm4.fsf@assigned-by-dhcp.cox.net>
Sometimes it is convient for a Porcelain to be able to checkout all
unmerged files in all stages so that an external merge tool can be
executed by the Porcelain or the end-user. Using git-unpack-file
on each stage individually incurs a rather high penalty due to the
need to fork for each file version obtained. git-checkout-index -a
--stage=all will now do the same thing, but faster.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
This replaces my prior patch. It looks a heck of a lot cleaner too
due to less indentation changes. :-)
Junio C Hamano <junkio@cox.net> wrote:
> Shawn Pearce <spearce@spearce.org> writes:
>
> > Junio C Hamano <junkio@cox.net> wrote:
> >> Shawn Pearce <spearce@spearce.org> writes:
> >>
> >> > Unfortunately this change lead me down a path which changed the core
> >> > checkout code also used by apply and read-tree.
> >>
>
> I would have preferred not to add to_tempfile member to the
> checkout struct. Instead, if checkout_entry has non NULL
> topath, check out to a temporary location and return the path;
> otherwise behave the way it did before.
Good idea.
> I am unsure about what the tempfile option should do when asked
> to checkout a symbolic link. Creating a temporary regular file
> that has the readlink result does not sound very useful to me.
I couldn't decide either here; but there's no `mkstemplink'
or some-such function to generate a temporary symbolic link.
With the target in a temp file a Porcelain can at least generate
a true symbolic link with the correct target or present it the
different versions to the user for resolution. Symlinks are
definately difficult.
> BTW, in any case, I think there is one breakage that needs to be
> fixed with something like this...
That should be fixed with this version of the patch. Good catch.
Documentation/git-checkout-index.txt | 51 ++++++++
apply.c | 3
cache.h | 2
checkout-index.c | 86 ++++++++++++--
entry.c | 40 +++++-
read-tree.c | 2
t/t2004-checkout-cache-temp.sh | 212 ++++++++++++++++++++++++++++++++++
7 files changed, 370 insertions(+), 26 deletions(-)
create mode 100755 t/t2004-checkout-cache-temp.sh
base 1c7fee5d0857d809fe5d93a1d56968e44296ce55
last aa1305c3181ac1a3a493765bf41c2d59f8b8ce3e
diff --git a/Documentation/git-checkout-index.txt b/Documentation/git-checkout-index.txt
index b0b6588..09bd6a5 100644
--- a/Documentation/git-checkout-index.txt
+++ b/Documentation/git-checkout-index.txt
@@ -10,7 +10,8 @@ SYNOPSIS
--------
[verse]
'git-checkout-index' [-u] [-q] [-a] [-f] [-n] [--prefix=<string>]
- [--stage=<number>]
+ [--stage=<number>|all]
+ [--temp]
[-z] [--stdin]
[--] [<file>]\*
@@ -43,9 +44,15 @@ OPTIONS
When creating files, prepend <string> (usually a directory
including a trailing /)
---stage=<number>::
+--stage=<number>|all::
Instead of checking out unmerged entries, copy out the
files from named stage. <number> must be between 1 and 3.
+ Note: --stage=all automatically implies --temp.
+
+--temp::
+ Instead of copying the files to the working directory
+ write the content to temporary files. The temporary name
+ associations will be written to stdout.
--stdin::
Instead of taking list of paths from the command line,
@@ -87,6 +94,46 @@ it will prevent problems with a filename
Using `--` is probably a good policy in scripts.
+Using --temp or --stage=all
+---------------------------
+When `--temp` is used (or implied by `--stage=all`)
+`git-checkout-index` will create a temporary file for each index
+entry being checked out. The index will not be updated with stat
+information. These options can be useful if the caller needs all
+stages of all unmerged entries so that the unmerged files can be
+processed by an external merge tool.
+
+A listing will be written to stdout providing the association of
+temporary file names to tracked path names. The listing format
+has two variations:
+
+ . tempname TAB path RS
++
+The first format is what gets used when `--stage` is omitted or
+is not `--stage=all`. The field tempname is the temporary file
+name holding the file content and path is the tracked path name in
+the index. Only the requested entries are output.
+
+ . stage1temp SP stage2temp SP stage3tmp TAB path RS
++
+The second format is what gets used when `--stage=all`. The three
+stage temporary fields (stage1temp, stage2temp, stage3temp) list the
+name of the temporary file if there is a stage entry in the index
+or `.` if there is no stage entry. Paths which only have a stage 0
+entry will always be omitted from the output.
+
+In both formats RS (the record separator) is newline by default
+but will be the null byte if -z was passed on the command line.
+The temporary file names are always safe strings; they will never
+contain directory separators or whitespace characters. The path
+field is always relative to the current directory and the temporary
+file names are always relative to the top level directory.
+
+If the object being copied out to a temporary file is a symbolic
+link the content of the link will be written to a normal file. It is
+up to the end-user or the Porcelain to make use of this information.
+
+
EXAMPLES
--------
To update and refresh only the files already checked out::
diff --git a/apply.c b/apply.c
index c369966..849a8b4 100644
--- a/apply.c
+++ b/apply.c
@@ -1402,7 +1402,8 @@ static int check_patch(struct patch *pat
costate.not_new = 0;
costate.refresh_cache = 1;
if (checkout_entry(active_cache[pos],
- &costate) ||
+ &costate,
+ NULL) ||
lstat(old_name, &st))
return -1;
}
diff --git a/cache.h b/cache.h
index 8dc1de1..1f96280 100644
--- a/cache.h
+++ b/cache.h
@@ -262,7 +262,7 @@ struct checkout {
refresh_cache:1;
};
-extern int checkout_entry(struct cache_entry *ce, struct checkout *state);
+extern int checkout_entry(struct cache_entry *ce, struct checkout *state, char *topath);
extern struct alternate_object_database {
struct alternate_object_database *next;
diff --git a/checkout-index.c b/checkout-index.c
index f54c606..7b78715 100644
--- a/checkout-index.c
+++ b/checkout-index.c
@@ -40,9 +40,13 @@
#include "strbuf.h"
#include "quote.h"
+#define CHECKOUT_ALL 4
static const char *prefix;
static int prefix_length;
+static int line_termination = '\n';
static int checkout_stage; /* default to checkout stage0 */
+static int to_tempfile;
+static char topath[4][MAXPATHLEN+1];
static struct checkout state = {
.base_dir = "",
@@ -53,11 +57,39 @@ static struct checkout state = {
.refresh_cache = 0,
};
+static void write_tempfile_record (const char *name)
+{
+ int i;
+
+ if (CHECKOUT_ALL == checkout_stage) {
+ for (i = 1; i < 4; i++) {
+ if (i > 1)
+ putchar(' ');
+ if (topath[i][0])
+ fputs(topath[i], stdout);
+ else
+ putchar('.');
+ }
+ } else
+ fputs(topath[checkout_stage], stdout);
+
+ putchar('\t');
+ write_name_quoted("", 0, name + prefix_length,
+ line_termination, stdout);
+ putchar(line_termination);
+
+ for (i = 0; i < 4; i++) {
+ topath[i][0] = 0;
+ }
+}
+
static int checkout_file(const char *name)
{
int namelen = strlen(name);
int pos = cache_name_pos(name, namelen);
int has_same_name = 0;
+ int did_checkout = 0;
+ int errs = 0;
if (pos < 0)
pos = -pos - 1;
@@ -68,9 +100,20 @@ static int checkout_file(const char *nam
memcmp(ce->name, name, namelen))
break;
has_same_name = 1;
- if (checkout_stage == ce_stage(ce))
- return checkout_entry(ce, &state);
pos++;
+ if (ce_stage(ce) != checkout_stage
+ && (CHECKOUT_ALL != checkout_stage || !ce_stage(ce)))
+ continue;
+ did_checkout = 1;
+ if (checkout_entry(ce, &state,
+ to_tempfile ? topath[ce_stage(ce)] : NULL) < 0)
+ errs++;
+ }
+
+ if (did_checkout) {
+ if (to_tempfile)
+ write_tempfile_record(name);
+ return errs > 0 ? -1 : 0;
}
if (!state.quiet) {
@@ -90,18 +133,29 @@ static int checkout_file(const char *nam
static int checkout_all(void)
{
int i, errs = 0;
+ struct cache_entry* last_ce = 0;
for (i = 0; i < active_nr ; i++) {
struct cache_entry *ce = active_cache[i];
- if (ce_stage(ce) != checkout_stage)
+ if (ce_stage(ce) != checkout_stage
+ && (CHECKOUT_ALL != checkout_stage || !ce_stage(ce)))
continue;
if (prefix && *prefix &&
(ce_namelen(ce) <= prefix_length ||
memcmp(prefix, ce->name, prefix_length)))
continue;
- if (checkout_entry(ce, &state) < 0)
+ if (last_ce && to_tempfile) {
+ if (ce_namelen(last_ce) != ce_namelen(ce)
+ || memcmp(last_ce->name, ce->name, ce_namelen(ce)))
+ write_tempfile_record(last_ce->name);
+ }
+ if (checkout_entry(ce, &state,
+ to_tempfile ? topath[ce_stage(ce)] : NULL) < 0)
errs++;
+ last_ce = ce;
}
+ if (last_ce && to_tempfile)
+ write_tempfile_record(last_ce->name);
if (errs)
/* we have already done our error reporting.
* exit with the same code as die().
@@ -111,7 +165,7 @@ static int checkout_all(void)
}
static const char checkout_cache_usage[] =
-"git-checkout-index [-u] [-q] [-a] [-f] [-n] [--stage=[123]] [--prefix=<string>] [--] <file>...";
+"git-checkout-index [-u] [-q] [-a] [-f] [-n] [--stage=[123]|all] [--prefix=<string>] [--temp] [--] <file>...";
static struct cache_file cache_file;
@@ -121,7 +175,6 @@ int main(int argc, char **argv)
int newfd = -1;
int all = 0;
int read_from_stdin = 0;
- int line_termination = '\n';
prefix = setup_git_directory();
git_config(git_default_config);
@@ -175,17 +228,26 @@ int main(int argc, char **argv)
i++; /* do not consider arg as a file name */
break;
}
+ if (!strcmp(arg, "--temp")) {
+ to_tempfile = 1;
+ continue;
+ }
if (!strncmp(arg, "--prefix=", 9)) {
state.base_dir = arg+9;
state.base_dir_len = strlen(state.base_dir);
continue;
}
if (!strncmp(arg, "--stage=", 8)) {
- int ch = arg[8];
- if ('1' <= ch && ch <= '3')
- checkout_stage = arg[8] - '0';
- else
- die("stage should be between 1 and 3");
+ if (!strcmp(arg + 8, "all")) {
+ to_tempfile = 1;
+ checkout_stage = CHECKOUT_ALL;
+ } else {
+ int ch = arg[8];
+ if ('1' <= ch && ch <= '3')
+ checkout_stage = arg[8] - '0';
+ else
+ die("stage should be between 1 and 3 or all");
+ }
continue;
}
if (arg[0] == '-')
@@ -193,7 +255,7 @@ int main(int argc, char **argv)
break;
}
- if (state.base_dir_len) {
+ if (state.base_dir_len || to_tempfile) {
/* when --prefix is specified we do not
* want to update cache.
*/
diff --git a/entry.c b/entry.c
index 8fb99bc..38b5241 100644
--- a/entry.c
+++ b/entry.c
@@ -63,7 +63,7 @@ static int create_file(const char *path,
return open(path, O_WRONLY | O_CREAT | O_EXCL, mode);
}
-static int write_entry(struct cache_entry *ce, const char *path, struct checkout *state)
+static int write_entry(struct cache_entry *ce, char *path, struct checkout *state, int to_tempfile)
{
int fd;
void *new;
@@ -80,7 +80,11 @@ static int write_entry(struct cache_entr
}
switch (ntohl(ce->ce_mode) & S_IFMT) {
case S_IFREG:
- fd = create_file(path, ntohl(ce->ce_mode));
+ if (to_tempfile) {
+ strcpy(path, ".merge_file_XXXXXX");
+ fd = mkstemp(path);
+ } else
+ fd = create_file(path, ntohl(ce->ce_mode));
if (fd < 0) {
free(new);
return error("git-checkout-index: unable to create file %s (%s)",
@@ -93,12 +97,27 @@ static int write_entry(struct cache_entr
return error("git-checkout-index: unable to write file %s", path);
break;
case S_IFLNK:
- if (symlink(new, path)) {
+ if (to_tempfile) {
+ strcpy(path, ".merge_link_XXXXXX");
+ fd = mkstemp(path);
+ if (fd < 0) {
+ free(new);
+ return error("git-checkout-index: unable to create "
+ "file %s (%s)", path, strerror(errno));
+ }
+ wrote = write(fd, new, size);
+ close(fd);
free(new);
- return error("git-checkout-index: unable to create "
- "symlink %s (%s)", path, strerror(errno));
+ if (wrote != size)
+ return error("git-checkout-index: unable to write file %s",
+ path);
+ } else {
+ wrote = symlink(new, path);
+ free(new);
+ if (wrote)
+ return error("git-checkout-index: unable to create "
+ "symlink %s (%s)", path, strerror(errno));
}
- free(new);
break;
default:
free(new);
@@ -113,12 +132,15 @@ static int write_entry(struct cache_entr
return 0;
}
-int checkout_entry(struct cache_entry *ce, struct checkout *state)
+int checkout_entry(struct cache_entry *ce, struct checkout *state, char *topath)
{
- struct stat st;
static char path[MAXPATHLEN+1];
+ struct stat st;
int len = state->base_dir_len;
+ if (topath)
+ return write_entry(ce, topath, state, 1);
+
memcpy(path, state->base_dir, len);
strcpy(path + len, ce->name);
@@ -147,7 +169,7 @@ int checkout_entry(struct cache_entry *c
} else if (state->not_new)
return 0;
create_directories(path, state);
- return write_entry(ce, path, state);
+ return write_entry(ce, path, state, 0);
}
diff --git a/read-tree.c b/read-tree.c
index be29b3f..1c3b09b 100644
--- a/read-tree.c
+++ b/read-tree.c
@@ -337,7 +337,7 @@ static void check_updates(struct cache_e
if (ce->ce_flags & mask) {
ce->ce_flags &= ~mask;
if (update)
- checkout_entry(ce, &state);
+ checkout_entry(ce, &state, NULL);
}
}
if (total) {
diff --git a/t/t2004-checkout-cache-temp.sh b/t/t2004-checkout-cache-temp.sh
new file mode 100755
index 0000000..c100959
--- /dev/null
+++ b/t/t2004-checkout-cache-temp.sh
@@ -0,0 +1,212 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 Shawn Pearce
+#
+
+test_description='git-checkout-index --temp test.
+
+With --temp flag, git-checkout-index writes to temporary merge files
+rather than the tracked path.'
+
+. ./test-lib.sh
+
+test_expect_success \
+'preparation' '
+mkdir asubdir &&
+echo tree1path0 >path0 &&
+echo tree1path1 >path1 &&
+echo tree1path3 >path3 &&
+echo tree1path4 >path4 &&
+echo tree1asubdir/path5 >asubdir/path5 &&
+git-update-index --add path0 path1 path3 path4 asubdir/path5 &&
+t1=$(git-write-tree) &&
+rm -f path* .merge_* out .git/index &&
+echo tree2path0 >path0 &&
+echo tree2path1 >path1 &&
+echo tree2path2 >path2 &&
+echo tree2path4 >path4 &&
+git-update-index --add path0 path1 path2 path4 &&
+t2=$(git-write-tree) &&
+rm -f path* .merge_* out .git/index &&
+echo tree2path0 >path0 &&
+echo tree3path1 >path1 &&
+echo tree3path2 >path2 &&
+echo tree3path3 >path3 &&
+git-update-index --add path0 path1 path2 path3 &&
+t3=$(git-write-tree)'
+
+test_expect_success \
+'checkout one stage 0 to temporary file' '
+rm -f path* .merge_* out .git/index &&
+git-read-tree $t1 &&
+git-checkout-index --temp -- path1 >out &&
+test $(wc -l <out) = 1 &&
+test $(cut "-d " -f2 out) = path1 &&
+p=$(cut "-d " -f1 out) &&
+test -f $p &&
+test $(cat $p) = tree1path1'
+
+test_expect_success \
+'checkout all stage 0 to temporary files' '
+rm -f path* .merge_* out .git/index &&
+git-read-tree $t1 &&
+git-checkout-index -a --temp >out &&
+test $(wc -l <out) = 5 &&
+for f in path0 path1 path3 path4 asubdir/path5
+do
+ test $(grep $f out | cut "-d " -f2) = $f &&
+ p=$(grep $f out | cut "-d " -f1) &&
+ test -f $p &&
+ test $(cat $p) = tree1$f
+done'
+
+test_expect_success \
+'prepare 3-way merge' '
+rm -f path* .merge_* out .git/index &&
+git-read-tree -m $t1 $t2 $t3'
+
+test_expect_success \
+'checkout one stage 2 to temporary file' '
+rm -f path* .merge_* out &&
+git-checkout-index --stage=2 --temp -- path1 >out &&
+test $(wc -l <out) = 1 &&
+test $(cut "-d " -f2 out) = path1 &&
+p=$(cut "-d " -f1 out) &&
+test -f $p &&
+test $(cat $p) = tree2path1'
+
+test_expect_success \
+'checkout all stage 2 to temporary files' '
+rm -f path* .merge_* out &&
+git-checkout-index --all --stage=2 --temp >out &&
+test $(wc -l <out) = 3 &&
+for f in path1 path2 path4
+do
+ test $(grep $f out | cut "-d " -f2) = $f &&
+ p=$(grep $f out | cut "-d " -f1) &&
+ test -f $p &&
+ test $(cat $p) = tree2$f
+done'
+
+test_expect_success \
+'checkout all stages/one file to nothing' '
+rm -f path* .merge_* out &&
+git-checkout-index --stage=all --temp -- path0 >out &&
+test $(wc -l <out) = 0'
+
+test_expect_success \
+'checkout all stages/one file to temporary files' '
+rm -f path* .merge_* out &&
+git-checkout-index --stage=all --temp -- path1 >out &&
+test $(wc -l <out) = 1 &&
+test $(cut "-d " -f2 out) = path1 &&
+cut "-d " -f1 out | (read s1 s2 s3 &&
+test -f $s1 &&
+test -f $s2 &&
+test -f $s3 &&
+test $(cat $s1) = tree1path1 &&
+test $(cat $s2) = tree2path1 &&
+test $(cat $s3) = tree3path1)'
+
+test_expect_success \
+'checkout some stages/one file to temporary files' '
+rm -f path* .merge_* out &&
+git-checkout-index --stage=all --temp -- path2 >out &&
+test $(wc -l <out) = 1 &&
+test $(cut "-d " -f2 out) = path2 &&
+cut "-d " -f1 out | (read s1 s2 s3 &&
+test $s1 = . &&
+test -f $s2 &&
+test -f $s3 &&
+test $(cat $s2) = tree2path2 &&
+test $(cat $s3) = tree3path2)'
+
+test_expect_success \
+'checkout all stages/all files to temporary files' '
+rm -f path* .merge_* out &&
+git-checkout-index -a --stage=all --temp >out &&
+test $(wc -l <out) = 5'
+
+test_expect_success \
+'-- path0: no entry' '
+test x$(grep path0 out | cut "-d " -f2) = x'
+
+test_expect_success \
+'-- path1: all 3 stages' '
+test $(grep path1 out | cut "-d " -f2) = path1 &&
+grep path1 out | cut "-d " -f1 | (read s1 s2 s3 &&
+test -f $s1 &&
+test -f $s2 &&
+test -f $s3 &&
+test $(cat $s1) = tree1path1 &&
+test $(cat $s2) = tree2path1 &&
+test $(cat $s3) = tree3path1)'
+
+test_expect_success \
+'-- path2: no stage 1, have stage 2 and 3' '
+test $(grep path2 out | cut "-d " -f2) = path2 &&
+grep path2 out | cut "-d " -f1 | (read s1 s2 s3 &&
+test $s1 = . &&
+test -f $s2 &&
+test -f $s3 &&
+test $(cat $s2) = tree2path2 &&
+test $(cat $s3) = tree3path2)'
+
+test_expect_success \
+'-- path3: no stage 2, have stage 1 and 3' '
+test $(grep path3 out | cut "-d " -f2) = path3 &&
+grep path3 out | cut "-d " -f1 | (read s1 s2 s3 &&
+test -f $s1 &&
+test $s2 = . &&
+test -f $s3 &&
+test $(cat $s1) = tree1path3 &&
+test $(cat $s3) = tree3path3)'
+
+test_expect_success \
+'-- path4: no stage 3, have stage 1 and 3' '
+test $(grep path4 out | cut "-d " -f2) = path4 &&
+grep path4 out | cut "-d " -f1 | (read s1 s2 s3 &&
+test -f $s1 &&
+test -f $s2 &&
+test $s3 = . &&
+test $(cat $s1) = tree1path4 &&
+test $(cat $s2) = tree2path4)'
+
+test_expect_success \
+'-- asubdir/path5: no stage 2 and 3 have stage 1' '
+test $(grep asubdir/path5 out | cut "-d " -f2) = asubdir/path5 &&
+grep asubdir/path5 out | cut "-d " -f1 | (read s1 s2 s3 &&
+test -f $s1 &&
+test $s2 = . &&
+test $s3 = . &&
+test $(cat $s1) = tree1asubdir/path5)'
+
+test_expect_success \
+'checkout --temp within subdir' '
+(cd asubdir &&
+ git-checkout-index -a --stage=all >out &&
+ test $(wc -l <out) = 1 &&
+ test $(grep path5 out | cut "-d " -f2) = path5 &&
+ grep path5 out | cut "-d " -f1 | (read s1 s2 s3 &&
+ test -f ../$s1 &&
+ test $s2 = . &&
+ test $s3 = . &&
+ test $(cat ../$s1) = tree1asubdir/path5)
+)'
+
+test_expect_success \
+'checkout --temp symlink' '
+rm -f path* .merge_* out .git/index &&
+ln -s b a &&
+git-update-index --add a &&
+t4=$(git-write-tree) &&
+rm -f .git/index &&
+git-read-tree $t4 &&
+git-checkout-index --temp -a >out &&
+test $(wc -l <out) = 1 &&
+test $(cut "-d " -f2 out) = a &&
+p=$(cut "-d " -f1 out) &&
+test -f $p &&
+test $(cat $p) = b'
+
+test_done
--
1.2.4.g0226
^ permalink raw reply related
* [PATCH] cosmetics: change from 'See-Also' to 'See Also'
From: Jeff Muizelaar @ 2006-03-05 6:20 UTC (permalink / raw)
To: git
Changes the documentation that uses 'See-Also' to the more common
'See Also' form.
---
Documentation/git-pack-objects.txt | 2 +-
Documentation/git-pack-redundant.txt | 2 +-
Documentation/git-prune-packed.txt | 2 +-
Documentation/git-repack.txt | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
a4de726b80fe261856b9086b32f6e879f5ff0013
diff --git a/Documentation/git-pack-objects.txt b/Documentation/git-pack-objects.txt
index 4cb2e83..567dabf 100644
--- a/Documentation/git-pack-objects.txt
+++ b/Documentation/git-pack-objects.txt
@@ -101,7 +101,7 @@ Documentation
-------------
Documentation by Junio C Hamano
-See-Also
+See Also
--------
gitlink:git-repack[1]
gitlink:git-prune-packed[1]
diff --git a/Documentation/git-pack-redundant.txt b/Documentation/git-pack-redundant.txt
index 9fe86ae..2f4cc46 100644
--- a/Documentation/git-pack-redundant.txt
+++ b/Documentation/git-pack-redundant.txt
@@ -46,7 +46,7 @@ Documentation
--------------
Documentation by Lukas Sandström <lukass@etek.chalmers.se>
-See-Also
+See Also
--------
gitlink:git-pack-objects[1]
gitlink:git-repack[1]
diff --git a/Documentation/git-prune-packed.txt b/Documentation/git-prune-packed.txt
index 37c53a9..2348826 100644
--- a/Documentation/git-prune-packed.txt
+++ b/Documentation/git-prune-packed.txt
@@ -40,7 +40,7 @@ Documentation
--------------
Documentation by Ryan Anderson <ryan@michonline.com>
-See-Also
+See Also
--------
gitlink:git-pack-objects[1]
gitlink:git-repack[1]
diff --git a/Documentation/git-repack.txt b/Documentation/git-repack.txt
index 6c0f792..d2f9a44 100644
--- a/Documentation/git-repack.txt
+++ b/Documentation/git-repack.txt
@@ -63,7 +63,7 @@ Documentation
--------------
Documentation by Ryan Anderson <ryan@michonline.com>
-See-Also
+See Also
--------
gitlink:git-pack-objects[1]
gitlink:git-prune-packed[1]
--
1.2.4.g8bc6
^ permalink raw reply related
* Re: What's in git.git
From: Junio C Hamano @ 2006-03-05 5:44 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0603042058250.13139@g5.osdl.org>
Linus Torvalds <torvalds@osdl.org> writes:
> I'm not sure this is worth it, but it looks obvious enough. Somebody with
> gitweb somewhere should probably check if it still even wants this.
I just pulled and it's still v264 (Jan 17 2006). It does it in
one sub (git_read_commit) to read a single commit and the sub is
called from almost everywhere, so it would help.
Having said that...
> diff --git a/revision.c b/revision.c
> index a3df810..33a5f20 100644
> --- a/revision.c
> +++ b/revision.c
> @@ -696,6 +696,18 @@ struct commit *get_revision(struct rev_i
> break;
> case 0:
> return NULL;
> +
> + /* Special case to avoid unnecessary parent checking */
> + case 1:
> + if (!revs->limited &&
> + !revs->no_merges &&
> + !revs->paths &&
> + revs->min_age == -1 &&
> + revs->max_age == -1) {
> + revs->max_count = 0;
> + commit->object.flags |= SHOWN;
> + return commit;
> + }
At this point commit is revs->commits->item. It cannot be
UNINTERESTING because you make it sure with !revs->limited and
friends, but I wonder if it can be SHOWN already for some
reason, in which case returning it is wrong.
Unlike the earlier special case in rev-list, this special case
kicks in for the last iteration of repeated calls to
get_revision() (e.g. third iteration of "rev-list -3")...
^ permalink raw reply
* Re: [PATCH] Add --temp and --stage=all options to checkout-index.
From: Junio C Hamano @ 2006-03-05 5:29 UTC (permalink / raw)
To: Shawn Pearce; +Cc: git
In-Reply-To: <20060303151331.GA16369@spearce.org>
Shawn Pearce <spearce@spearce.org> writes:
> Junio C Hamano <junkio@cox.net> wrote:
>> Shawn Pearce <spearce@spearce.org> writes:
>>
>> > Unfortunately this change lead me down a path which changed the core
>> > checkout code also used by apply and read-tree.
>>
I would have preferred not to add to_tempfile member to the
checkout struct. Instead, if checkout_entry has non NULL
topath, check out to a temporary location and return the path;
otherwise behave the way it did before.
That way everybody else would not need to declare useless
topath[] array on the stack and pass it to checkout_entry
(instead they would just pass NULL because they are not
interested in checking out to temporary files).
I am unsure about what the tempfile option should do when asked
to checkout a symbolic link. Creating a temporary regular file
that has the readlink result does not sound very useful to me.
BTW, in any case, I think there is one breakage that needs to be
fixed with something like this...
---
diff --git a/apply.c b/apply.c
index 5a2cf54..727d63d 100644
--- a/apply.c
+++ b/apply.c
@@ -1311,6 +1311,7 @@ static int check_patch(struct patch *pat
costate.force = 0;
costate.quiet = 0;
costate.not_new = 0;
+ costate.to_tempfile = 0;
costate.refresh_cache = 1;
if (checkout_entry(active_cache[pos],
&costate, topath) ||
^ permalink raw reply related
* Re: What's in git.git
From: Linus Torvalds @ 2006-03-05 4:58 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vacc5jza6.fsf@assigned-by-dhcp.cox.net>
On Sat, 4 Mar 2006, Junio C Hamano wrote:
>
> The most notable core-ish change is that rev-list split and new
> git-log implementation by Linus. I've been using this myself
> for a while without problems, but there might still be some
> corner cases that I (and Linus perhaps) do not exercise where
> git-log command behaves slightly differently. rev-list is not
> supposed to have *any* regression other than removal of
> --merge-order. Please report regressions.
Here's a potential fix for a special case that we used to have to make
git-rev-list --max-count=1
be faster and not unnecessarily parse any parent objects.
Now, we had that special case because gitweb was apparently doing a lot of
it, and quite frankly, I don't know if it still does. But basically it
avoids doing the "pop_most_recent_commit()" which will look up and parse
the parents, if it is obvious that it can.
I'm not sure this is worth it, but it looks obvious enough. Somebody with
gitweb somewhere should probably check if it still even wants this.
Linus
----
diff --git a/revision.c b/revision.c
index a3df810..33a5f20 100644
--- a/revision.c
+++ b/revision.c
@@ -696,6 +696,18 @@ struct commit *get_revision(struct rev_i
break;
case 0:
return NULL;
+
+ /* Special case to avoid unnecessary parent checking */
+ case 1:
+ if (!revs->limited &&
+ !revs->no_merges &&
+ !revs->paths &&
+ revs->min_age == -1 &&
+ revs->max_age == -1) {
+ revs->max_count = 0;
+ commit->object.flags |= SHOWN;
+ return commit;
+ }
default:
revs->max_count--;
}
^ permalink raw reply related
* Re: What's in git.git
From: Junio C Hamano @ 2006-03-05 4:51 UTC (permalink / raw)
To: git
In-Reply-To: <7vacc5jza6.fsf@assigned-by-dhcp.cox.net>
Junio C Hamano <junkio@cox.net> writes:
> Fredrik's git-blame still has -Wdeclaration-after-statement
> issues,...
Quick correction before anybody says anything.
Sorry Fredrik, there is none anymore --- you have already done
clean-up and I merged it. Just "print_map defined but not used".
^ permalink raw reply
* What's in git.git
From: Junio C Hamano @ 2006-03-05 4:22 UTC (permalink / raw)
To: git
I've merged up a lot for people to have fun over the weekend
;-).
The most notable core-ish change is that rev-list split and new
git-log implementation by Linus. I've been using this myself
for a while without problems, but there might still be some
corner cases that I (and Linus perhaps) do not exercise where
git-log command behaves slightly differently. rev-list is not
supposed to have *any* regression other than removal of
--merge-order. Please report regressions.
A new killer application is git-cvsserver. It now talks pserver
protocol for anonymous CVS access. Helping Martin to audit the
code for any issues, security or otherwise, is greatly
appreciated.
Fredrik's git-blame still has -Wdeclaration-after-statement
issues, but deserves to be beaten harder alongside Ryan's
git-annotate for two reasons. It should be a good example
program to use the new revision traversal infrastructure, and it
is always good to have competing two implementations ;-).
* The 'master' branch has these since the last announcement.
- Cygwin portability for test (Alex Riesen)
workaround fat/ntfs deficiencies for t3600-rm.sh (git-rm)
- Emacs interface (Alexandre Julliard)
contrib/emacs: Add an Emacs VC backend.
git.el: Added customize support for all parameters.
git.el: Added support for Signed-off-by.
git.el: Automatically update .gitignore status.
git.el: Portability fixes for XEmacs and Emacs CVS.
git.el: Set default directory before running the status mode setup hooks.
- gitview updates (Aneesh Kumar K.V)
gitview: Use horizontal scroll bar in the tree view
gitview: pass the missing argument _show_clicked_cb.
- git-svn updates (Eric Wong)
contrib/git-svn: add --id/-i=$GIT_SVN_ID command-line switch
contrib/git-svn: add -b/--branch switch for branch detection
contrib/git-svn: allow --authors-file to be specified
contrib/git-svn: avoid re-reading the repository uuid, it never changes
contrib/git-svn: better documenting of CLI switches
contrib/git-svn: cleanup option parsing
contrib/git-svn: create a more recent master if one does not exist
contrib/git-svn: fix a copied-tree bug in an overzealous assertion
contrib/git-svn: several small bug fixes and changes
contrib/git-svn: strip 'git-svn-id:' when commiting to SVN
contrib/git-svn: use refs/remotes/git-svn instead of git-svn-HEAD
git-branch: add -r switch to list refs/remotes/*
- send-email fix (Eric Wong)
send-email: accept --no-signed-off-by-cc as the documentation states
- checkout-index --stdin (Shawn Pearce)
Teach git-checkout-index to read filenames from stdin.
- git-blame (Fredrik Kuivinen)
Add git-blame, a tool for assigning blame.
git-blame, take 2
- git-mv updates (Josef Weidendorfer)
git-mv: Allow -h without repo & fix error message
git-mv: fixes for path handling
git-mv: fix moves into a subdir from outside
- split rev-list implementation and git-log (Linus and me)
First cut at libifying revlist generation
Splitting rev-list into revisions lib, end of beginning.
git-rev-list libification: rev-list walking
Introduce trivial new pager.c helper infrastructure
Tie it all together: "git log"
Rip out merge-order and make "git log <paths>..." work again.
rev-list split: minimum fixup.
git-log (internal): add approxidate.
git-log (internal): more options.
setup_revisions(): handle -n<n> and -<n> internally.
- git-verify-tag update (me)
Pretty-print tagger dates.
- git-commit --amend (me)
- show-branch --topics (me)
- git-svnimport update (Karl Hasselström)
Save username -> Full Name <email@addr.es> map file
- git tool survey documentation (Marco Costalba)
Add a Documentation/git-tools.txt
- git-cvsserver updates (Martin Langhoff)
cvsserver: Checkout correctly on Eclipse
annotate: fix -S parameter to take a string
cvsserver: Eclipse compat -- now "compare with latest from HEAD" works
cvsserver: checkout faster by sending files in a sensible order
cvsserver: fix checkouts with -d <somedir>
cvsserver: nested directory creation fixups for Eclipse clients
cvsserver: better error messages
cvsserver: anonymous cvs via pserver support
- delta cleanup (Nicolas Pitre)
relax delta selection filtering in pack-objects
diff-delta: fold two special tests into one plus cleanups
diff-delta: big code simplification
- git-annotate updates (Ryan Anderson)
annotate: handle \No newline at end of file.
annotate: Add a basic set of test cases.
- misc fixes and docs (Francis Daly, Johannes Schindelin, Jonas Fonseca,
Mark Wooding, Shawn Pearce, Tony Luck, Martin Langhoff, me)
AsciiDoc fix for tutorial
Documentation: read-tree --aggressive
Documentation: rev-list --objects-edge
Fix test case for some sed
GIT-VERSION-GEN: squelch unneeded error from "cat version"
Prevent --index-info from ignoring -z.
Pull GIT 1.2.4 fixes from master
Re-fix compilation warnings.
Warn about invalid refs
annotate should number lines starting with 1
annotate: fix -S parameter to take a string
annotate: resurrect raw timestamps.
combine-diff: Honour --full-index.
combine-diff: Honour -z option correctly.
git-commit: make sure we protect against races.
manpages: insert two missing [verse] markers for multi-line SYNOPSIS
read-tree --aggressive: remove deleted entry from the working tree.
tar-tree: file/dirmode fix.
war on whitespaces: documentation.
* The 'next' branch, in addition, has these.
- diffcore-rename/break and similarity estimator tweaks (me)
count-delta: no need for this anymore.
diffcore-break: similarity estimator fix.
diffcore-delta: make change counter to byte oriented again.
diffcore-rename: similarity estimator fix.
* The 'pu' branch, in addition, has these.
- checkout-index --temp --stage=all (Shawn Pearce)
^ permalink raw reply
* Managing topic branches
From: Junio C Hamano @ 2006-03-05 1:56 UTC (permalink / raw)
To: git
I adopted Tony's excellent "topic branches" workflow to manage
the topics cooking in separate branches. The flow goes like
this:
- The change to the topic are made as new commits on top of
the topic branch. My naming convention for topic branches
are two letters directory under .git/refs/heads/ and short
word. E.g. np/delta for Nico's finer-grained delta work,
ml/cvsserver for Martin's git-cvsserver.
- To test topics myself and publish the bleeding edge to
others, updated topic branches are merged into "next". If I
have some changes to "master", the tip of it is also
merged into "next", so that people following "next" will not
miss out trivial fixes directly made to "master".
- Once a topic is fully cooked, it is merged into "master". I
delete the topic branch in my private repository (its tip is
already merged into "master" and also it was merged into
"next" long time ago).
This worked reasonably well, and I can see what are still not in
"master" but brewing in "next" with two ways:
- "git log master..next". This is the orthodox way to view
list of commits that are in next but still not in next.
Giving --no-merges option would help cutting down the
cluttering.
- "git show-branch --topics master 'heads/??/*'". (note: ??/*
is literally given to show-branch to let it glob).
However, the former started to break down recently, due to two
reasons.
1. np/delta turned out to be unsatisfactory, and I had reverts
and re-reverts in the topic branch. Eventually Nico and I
decided to throw away the last three commits after merging
the earlier bits into "master".
(other topic brances merged into next)
\ \ \ \ \ \
o---o---o---o---o---o---o---o---o next
/ / /
o---o---x---x---x---x---x np/delta
/ \ <-- earlier parts merged
o---o---o---o---o master
Some commits on "np/delta" merged into "next" are reverts and
the tip of "next" now do not have unwanted bits from the
finer-grained delta experiments. I have dropped np/delta topic
branch, so "show-branch --topics" does not bother me with these
commits marked with 'x' anymore, but "git log master..next" will
keep showing them
2. "ml/cvsserver" was initially based on then-current "next"
tip, because it depended on something else that was only
present in "next", but by the time I pulled it from Martin,
the pieces it depended on have already graduated to "master".
Since I wanted to have cvsserver in the "master" sooner than
everything else that were in "next" when Martin prepared these
commits, I ended up doing this:
Here is what the ancestry graph looked like when I received
cvsserver stuff:
a---b---c ml/cvsserver
/
o---o---o---o next
/ / / A: another topic ml/cvsserver
/ A B* depended on
/ \ B*: many other "unready" topics
o---o---o---o master
So I cherry-picked them on to "master", and merged both
"ml/cvsserver" and "master" into "next":
a---b---c ml/cvsserver
/ \ <-- questionable octopus leg
o---o---o---o-----------* next
/ / / /
/ o o /
/ \ /
o---o---o---o---a'--b'--c' master
I could have done without the "questionable octopus leg", but I
did so that when Martin pulled my "next" into his cvsserver
branch, he does not have to do the real merges [*1*]. But now
commits a---b---c comes back to haunt me whenever I do "git log
master..next".
The moral of the story is not to try to be nice to others
without thinking about its concequences ;-). I should have just
done without the "questionable octopus leg", and asked Martin to
discard and rebase his tip of the development to my "next" after
this merge.
Anyhow, what I ended up doing to make "log master..next" usable
again was to cauterize the tips of unwanted topic branches
merged into next by merging them into "master" branch using
"ours" strategy:
$ git checkout master
$ git merge -s ours "excuse for this" HEAD ml/cvsserver np/delta
Luckily, I have merged up all the B*'s from "next" to "master",
so this was possible, but otherwise until I either merge them to
"master" or decide to drop forever I needed to keep a---b---c
around in "log master..next" output for a loooong time X-<.
[Footnote]
*1* I briefly thought about doing this instead, but this is a
wrong thing to do:
a---b---c ml/cvsserver
/ \
o---o---o---o-------------------* next
/ / / \ /
/ A B* \ /
/ \ \ /
o---o---o---o-------------------* master
\ /
a'------b'------c'
(cherry picked)
At this point, master would claim to have merged B* but actually
it has not.
^ permalink raw reply
* Re: [PATCH] Use core.sharedrepository consistently.
From: Junio C Hamano @ 2006-03-04 23:38 UTC (permalink / raw)
To: Fernando J. Pereda; +Cc: git
In-Reply-To: <20060304230557.GB28469@ferdyx.org>
"Fernando J. Pereda" <ferdy@gentoo.org> writes:
> 'git init-db --shared' sets 'core.sharedRepository' but in
> setup.c 'core.sharedrepository' is checked instead.
I thought they were case insensitive..
^ permalink raw reply
* Re: [PATCH] Use core.sharedrepository consistently.
From: Linus Torvalds @ 2006-03-04 23:16 UTC (permalink / raw)
To: Fernando J. Pereda; +Cc: git
In-Reply-To: <20060304225125.GB8891@ferdyx.org>
On Sat, 4 Mar 2006, Fernando J. Pereda wrote:
>
> 'git init-db --shared' sets 'core.sharedRepository' but in
> setup.c 'core.sharedrepository' is checked instead.
It really shouldn't matter.
Case in a git config option name is always converted to lower case when
the config file is read, exactly so that you can use mixed case without
the actual readers caring. Lots of people prefer mixed-case for
human-readable info, ie
[Core]
Name=Linus Torvalds
will actually generate
core.name=Linus Torvalds
as the config variable.
So the code should have worked fine. Unless there is some bug somewhere.
Linus
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox