* [PATCH] Ensure author information is set before asking for commit message.
From: Sean @ 2006-05-14 1:51 UTC (permalink / raw)
To: git
It's better to find out you need to set your author information
properly before you enter a long commit message.
Signed-off-by: Sean Estabrooks <seanlkml@sympatico.ca>
---
git-commit.sh | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
ae880db6fc12a0774c25925abbcc353fe6c9e46f
diff --git a/git-commit.sh b/git-commit.sh
index 26cd7ca..866ed6c 100755
--- a/git-commit.sh
+++ b/git-commit.sh
@@ -640,6 +640,7 @@ case "$no_edit" in
exit 1
;;
esac
+ git-var GIT_AUTHOR_IDENT > /dev/null || die
${VISUAL:-${EDITOR:-vi}} "$GIT_DIR/COMMIT_EDITMSG"
;;
esac
--
1.3.2.g260bd
^ permalink raw reply related
* [PATCH] Add "--branches", "--tags" and "--remotes" options to git-rev-parse.
From: Sean @ 2006-05-14 1:43 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vd5ehu8og.fsf@assigned-by-dhcp.cox.net>
"git branch" uses "rev-parse --all" and becomes much too slow when
there are many tags (it scans all refs). Use the new "--branches"
option of rev-parse to speed things up.
Signed-off-by: Sean Estabrooks <seanlkml@sympatico.ca>
---
On Sat, 13 May 2006 10:38:23 -0700
Junio C Hamano <junkio@cox.net> wrote:
> Makes sense perhaps.
>
> I understand you added --tags for completeness. Probably it
> would make sense to add --remotes if you are shooting for that.
>
Hi Junio,
Here's an updated patch with --remotes as you asked. I appened _ref to the
new functions to make it clear that for_each_remote didn't have anything to
do with remote files. Also updated the "is_rev_argument" function which was
missed first time around.
On a related note, would it be okay to change "git tag -l" to produce a list
of tags without the "tags/" prefix in front of every tag as it does now?
Wanted to use the new "git rev-parse --tags" instead of "find" to produce
the list but am not sure how important backward compatibility is in that case.
Sean
Documentation/git-rev-parse.txt | 9 +++++++++
git-branch.sh | 3 +--
refs.c | 23 +++++++++++++++++++----
refs.h | 3 +++
rev-parse.c | 17 ++++++++++++++++-
5 files changed, 48 insertions(+), 7 deletions(-)
260bda5eb4effca1a1dd33beb7f7e962d3eab602
diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt
index 8b95df0..ab896fc 100644
--- a/Documentation/git-rev-parse.txt
+++ b/Documentation/git-rev-parse.txt
@@ -67,6 +67,15 @@ OPTIONS
--all::
Show all refs found in `$GIT_DIR/refs`.
+--branches::
+ Show branch refs found in `$GIT_DIR/refs/heads`.
+
+--tags::
+ Show tag refs found in `$GIT_DIR/refs/tags`.
+
+--remotes::
+ Show tag refs found in `$GIT_DIR/refs/remotes`.
+
--show-prefix::
When the command is invoked from a subdirectory, show the
path of the current directory relative to the top-level
diff --git a/git-branch.sh b/git-branch.sh
index ebcc898..134e68c 100755
--- a/git-branch.sh
+++ b/git-branch.sh
@@ -82,8 +82,7 @@ done
case "$#" in
0)
- git-rev-parse --symbolic --all |
- sed -ne 's|^refs/heads/||p' |
+ git-rev-parse --symbolic --branches |
sort |
while read ref
do
diff --git a/refs.c b/refs.c
index 275b914..6c91ae6 100644
--- a/refs.c
+++ b/refs.c
@@ -114,7 +114,7 @@ int read_ref(const char *filename, unsig
return -1;
}
-static int do_for_each_ref(const char *base, int (*fn)(const char *path, const unsigned char *sha1))
+static int do_for_each_ref(const char *base, int (*fn)(const char *path, const unsigned char *sha1), int trim)
{
int retval = 0;
DIR *dir = opendir(git_path("%s", base));
@@ -146,7 +146,7 @@ static int do_for_each_ref(const char *b
if (stat(git_path("%s", path), &st) < 0)
continue;
if (S_ISDIR(st.st_mode)) {
- retval = do_for_each_ref(path, fn);
+ retval = do_for_each_ref(path, fn, trim);
if (retval)
break;
continue;
@@ -160,7 +160,7 @@ static int do_for_each_ref(const char *b
"commit object!", path);
continue;
}
- retval = fn(path, sha1);
+ retval = fn(path + trim, sha1);
if (retval)
break;
}
@@ -180,7 +180,22 @@ int head_ref(int (*fn)(const char *path,
int for_each_ref(int (*fn)(const char *path, const unsigned char *sha1))
{
- return do_for_each_ref("refs", fn);
+ return do_for_each_ref("refs", fn, 0);
+}
+
+int for_each_tag_ref(int (*fn)(const char *path, const unsigned char *sha1))
+{
+ return do_for_each_ref("refs/tags", fn, 10);
+}
+
+int for_each_branch_ref(int (*fn)(const char *path, const unsigned char *sha1))
+{
+ return do_for_each_ref("refs/heads", fn, 11);
+}
+
+int for_each_remote_ref(int (*fn)(const char *path, const unsigned char *sha1))
+{
+ return do_for_each_ref("refs/remotes", fn, 13);
}
static char *ref_file_name(const char *ref)
diff --git a/refs.h b/refs.h
index 2625596..fa816c1 100644
--- a/refs.h
+++ b/refs.h
@@ -7,6 +7,9 @@ #define REFS_H
*/
extern int head_ref(int (*fn)(const char *path, const unsigned char *sha1));
extern int for_each_ref(int (*fn)(const char *path, const unsigned char *sha1));
+extern int for_each_tag_ref(int (*fn)(const char *path, const unsigned char *sha1));
+extern int for_each_branch_ref(int (*fn)(const char *path, const unsigned char *sha1));
+extern int for_each_remote_ref(int (*fn)(const char *path, const unsigned char *sha1));
/** Reads the refs file specified into sha1 **/
extern int get_ref_sha1(const char *ref, unsigned char *sha1);
diff --git a/rev-parse.c b/rev-parse.c
index 62e16af..4e2d9fb 100644
--- a/rev-parse.c
+++ b/rev-parse.c
@@ -36,6 +36,7 @@ static int is_rev_argument(const char *a
"--all",
"--bisect",
"--dense",
+ "--branches",
"--header",
"--max-age=",
"--max-count=",
@@ -45,7 +46,9 @@ static int is_rev_argument(const char *a
"--objects-edge",
"--parents",
"--pretty",
+ "--remotes",
"--sparse",
+ "--tags",
"--topo-order",
"--date-order",
"--unpacked",
@@ -165,7 +168,7 @@ int main(int argc, char **argv)
int i, as_is = 0, verify = 0;
unsigned char sha1[20];
const char *prefix = setup_git_directory();
-
+
git_config(git_default_config);
for (i = 1; i < argc; i++) {
@@ -255,6 +258,18 @@ int main(int argc, char **argv)
for_each_ref(show_reference);
continue;
}
+ if (!strcmp(arg, "--branches")) {
+ for_each_branch_ref(show_reference);
+ continue;
+ }
+ if (!strcmp(arg, "--tags")) {
+ for_each_tag_ref(show_reference);
+ continue;
+ }
+ if (!strcmp(arg, "--remotes")) {
+ for_each_remote_ref(show_reference);
+ continue;
+ }
if (!strcmp(arg, "--show-prefix")) {
if (prefix)
puts(prefix);
--
1.3.2.g575a1
^ permalink raw reply related
* Re: [RFC] Add "rcs format diff" support
From: Al Viro @ 2006-05-14 0:12 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Junio C Hamano, Git Mailing List, Al Viro, Davide Libenzi
In-Reply-To: <Pine.LNX.4.64.0605131405590.3866@g5.osdl.org>
On Sat, May 13, 2006 at 02:14:15PM -0700, Linus Torvalds wrote:
>
> Al was asking for the "diff -n" format, which is the old RCS format, and
> which is really easy to parse.
Heh... And I've just managed to get around that stuff on plain git. Have fun:
Use:
git-remap-data [git-diff arguments] > map
git-remap map <old-log >remapped-old
git-remap /dev/null <new-log >remapped-new
diff -u remapped-old remapped-new
with old-log and new-log being build/sparse/whatever logs produced on
trees in question (for values of "whatever logs" including e.g. grep -n
results, etc.)
git-remap-data builds the description of how lines of old tree are mapped
to the new one; git-remap is a filter using that data to massage log
from the old tree to new one; lines of form
<file>:<line>:<text>
are turned into
N:<new-file>:<new-line>:<text>
if they survive in new tree and
O:<file>:<line>:<text>
otherwise.
Here they are; enjoy. BTW, that puppy can be used on unified diffs with
zero context; won't catch renames, obviously...
git-remap-data.sh:
#!/bin/sh
GIT_DIFF_OPTS="-u 0" git-diff -M "$@" | git-remap
git-remap.c:
/*
* Copyright (c) 2006, Al Viro. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
char *prefix1 = "a/", *prefix2 = "b/";
size_t len1, len2;
char *line;
size_t size;
void die(char *s)
{
fprintf(stderr, "remap: %s\n", s);
exit(1);
}
void Enomem(void)
{
die("out of memory");
}
void Eio(void)
{
die("IO error");
}
int getline(FILE *f)
{
char *s;
if (!fgets(line, size, f)) {
if (!feof(f))
Eio();
return 0;
}
for (s = line + strlen(line); s[-1] != '\n'; s = s + strlen(s)) {
if (s == line + size - 1) {
line = realloc(line, 2 * size);
if (!line)
Enomem();
s = line + size - 1;
size *= 2;
}
if (!fgets(s, size - (s - line), f)) {
if (!feof(f))
Eio();
return 1;
}
}
s[-1] = '\0';
return 1;
}
/* to == 0 -> deletion */
struct range_map {
int from, to;
};
struct file_map {
char *name;
struct file_map *next;
char *new_name;
int count;
int allocated;
int last;
struct range_map ranges[];
};
struct file_map *alloc_map(char *name)
{
struct file_map *map;
map = malloc(sizeof(struct file_map) + 16 * sizeof(struct range_map));
if (!map)
Enomem();
map->name = map->new_name = strdup(name);
if (!map->name)
Enomem();
map->count = 0;
map->allocated = 16;
map->next = NULL;
map->last = 0;
return map;
}
/* this is 32bit FNV1 */
uint32_t FNV_hash(char *name)
{
uint32_t n = 0x811c9dc5;
while (*name) {
unsigned char c = *name++;
n *= 0x01000193;
n ^= c;
}
return n;
}
struct file_map *hash[1024];
int hash_map(struct file_map *map)
{
int n = FNV_hash(map->name) % 1024;
struct file_map **p = &hash[n];
while (*p) {
if (!strcmp((*p)->name, map->name))
return 0;
p = &(*p)->next;
}
*p = map;
if (map->new_name && !map->count)
return 0;
if (map->new_name && map->ranges[0].from != 1)
return 0;
return 1;
}
struct file_map *find_map(char *name)
{
static struct file_map *last = NULL;
int n = FNV_hash(name) % 1024;
struct file_map *p;
if (last && !strcmp(last->name, name))
return last;
for (p = hash[n]; p && strcmp(p->name, name); p = p->next)
;
if (p)
last = p;
return p;
}
void parse_map(char *name)
{
struct file_map *map = NULL;
struct range_map *range;
char *s;
FILE *f;
f = fopen(name, "r");
if (!f)
die("can't open map");
while (getline(f)) {
if (line[0] == 'D') {
if (map && !hash_map(map))
goto Ebadmap;
if (line[1] != ' ')
goto Ebadmap;
if (strchr(line + 2, ' '))
goto Ebadmap;
map = alloc_map(line + 2);
map->new_name = NULL;
continue;
}
if (line[0] == 'M') {
if (map && !hash_map(map))
goto Ebadmap;
if (line[1] != ' ')
goto Ebadmap;
s = strchr(line + 2, ' ');
if (!s)
goto Ebadmap;
*s++ = '\0';
if (strchr(s, ' '))
goto Ebadmap;
map = alloc_map(line + 2);
if (strcmp(line + 2, s)) {
map->new_name = strdup(s);
if (!map->new_name)
Enomem();
}
continue;
}
if (!map || !map->new_name)
goto Ebadmap;
if (map->count == map->allocated) {
int n = 2 * map->allocated;
map = realloc(map, sizeof(struct file_map) +
n * sizeof(struct range_map));
if (!map)
Enomem();
map->allocated = n;
}
range = &map->ranges[map->count++];
if (sscanf(line, "%d %d%*c", &range->from, &range->to) != 2)
goto Ebadmap;
if (range > map->ranges && range->from <= range[-1].from)
goto Ebadmap;
}
if (map && !hash_map(map))
goto Ebadmap;
fclose(f);
return;
Ebadmap:
die("bad map");
}
struct range_map *find_range(struct file_map *map, int l)
{
struct range_map *range = &map->ranges[map->last];
struct range_map *p;
if (range->from <= l) {
p = &map->ranges[map->count - 1];
if (p->from > l) {
for (p = range; p->from <= l; p++)
;
p--;
}
} else {
for (p = map->ranges; p->from <= l; p++)
;
p--;
}
map->last = p - map->ranges;
return p;
}
void mapline(void)
{
struct file_map *map;
struct range_map *range;
unsigned long l;
char *s1, *s2;
char *name;
s1 = strchr(line, ':');
if (!s1)
goto noise;
s2 = strchr(line, ' ');
if (s2 && s2 < s1)
goto noise;
l = strtoul(s1 + 1, &s2, 10);
if (s2 == s1 + 1 || *s2 != ':' || !l || l > INT_MAX)
goto noise;
*s1++ = *s2++ = '\0';
name = line;
map = find_map(line);
if (!map)
goto new;
if (!map->new_name)
goto old;
name = map->new_name;
range = find_range(map, l);
if (!range->to)
goto old;
l += range->to - range->from;
new:
printf("N:%s:%lu:%s\n", name, l, s2);
return;
old:
s1[-1] = s2[-1] = ':';
printf("O:%s\n", line);
return;
noise:
printf("%s\n", line);
}
int parse_hunk(int *l1, int *l2, int *n1, int *n2)
{
unsigned long n;
char *s, *p;
if (line[3] != '-')
return 0;
n = strtoul(line + 4, &s, 10);
if (s == line + 4 || n > INT_MAX)
return 0;
*l1 = n;
if (*s == ',') {
n = strtoul(s + 1, &p, 10);
if (p == s + 1 || n > INT_MAX)
return 0;
*n1 = n;
if (!n)
(*l1)++;
} else {
p = s;
*n1 = 1;
}
if (*p != ' ' || p[1] != '+')
return 0;
n = strtoul(p + 2, &s, 10);
if (s == p + 2 || n > INT_MAX)
return 0;
*l2 = n;
if (*s == ',') {
n = strtoul(s + 1, &p, 10);
if (p == s + 1 || n > INT_MAX)
return 0;
*n2 = n;
if (!n)
(*l2)++;
} else {
p = s;
*n2 = 1;
}
return 1;
}
void parse_diff(void)
{
int skipping = -1, suppress = 1;
char *name1 = NULL, *name2 = NULL;
int from = 1, to = 1;
int l1, l2, n1, n2;
enum cmd {
Diff, Hunk, New, Del, Copy, Rename, Junk
} cmd;
static struct { const char *s; size_t len; } pref[] = {
[Hunk] = {"@@ ", 3},
[Diff] = {"diff ", 5},
[New] = {"new file ", 9},
[Del] = {"deleted file ", 12},
[Copy] = {"copy from ", 10},
[Rename] = {"rename from ", 11},
[Junk] = {"", 0},
};
size_t len1 = strlen(prefix1), len2 = strlen(prefix2);
while (getline(stdin)) {
if (skipping > 0) {
switch (line[0]) {
case '+':
case '-':
case '\\':
continue;
}
}
for (cmd = 0; strncmp(line, pref[cmd].s, pref[cmd].len); cmd++)
;
switch (cmd) {
case Hunk:
if (skipping < 0)
goto Ediff;
if (!suppress) {
if (!skipping)
printf("M %s %s\n", name1, name2);
if (!parse_hunk(&l1, &l2, &n1, &n2))
goto Ediff;
if (l1 > from)
printf("%d %d\n", from, to);
if (n1)
printf("%d 0\n", l1);
from = l1 + n1;
to = l2 + n2;
}
skipping = 1;
break;
case Diff:
if (!suppress) {
if (!skipping)
printf("M %s %s\n", name1, name2);
printf("%d %d\n", from, to);
}
free(name1);
free(name2);
name2 = strrchr(line, ' ');
if (!name2)
goto Ediff;
*name2 = '\0';
name1 = strrchr(line, ' ');
if (!name1)
goto Ediff;
if (strncmp(name1 + 1, prefix1, len1))
goto Ediff;
if (strncmp(name2 + 1, prefix2, len2))
goto Ediff;
name1 = strdup(name1 + len1 + 1);
name2 = strdup(name2 + len2 + 1);
if (!name1 || !name2)
goto Ediff;
skipping = 0;
suppress = 0;
from = to = 1;
break;
case New:
if (skipping)
goto Ediff;
suppress = 1;
break;
case Del:
case Copy:
if (skipping)
goto Ediff;
printf("D %s\n", name2);
suppress = 1;
break;
case Rename:
if (skipping)
goto Ediff;
printf("D %s\n", name2);
break;
default:
break;
}
}
return;
Ediff:
die("odd diff");
}
int main(int argc, char **argv)
{
int skipping = 0;
size = 256;
line = malloc(size);
if (!line)
Enomem();
if (argc < 2) {
parse_diff();
} else {
parse_map(argv[1]);
while (getline(stdin))
mapline();
}
return 0;
}
^ permalink raw reply
* Re: git diff: support "-U" and "--unified" options properly
From: Linus Torvalds @ 2006-05-13 22:39 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vpsihsjq6.fsf@assigned-by-dhcp.cox.net>
On Sat, 13 May 2006, Junio C Hamano wrote:
>
> * built-in grep (jc/grep)
>
> Ready.
I'm not entirely convinced.
For the kernel, I currently can do a
git grep some-random-string
in about half a second.
The new built-in grep is about ten times slower.
Before:
[torvalds@g5 linux]$ /usr/bin/time git grep some-random-string
Command exited with non-zero status 123
0.29user 0.30system 0:00.52elapsed 113%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+3206minor)pagefaults 0swaps
After:
[torvalds@g5 linux]$ /usr/bin/time git grep some-random-string
Command exited with non-zero status 1
4.60user 0.33system 0:04.98elapsed 98%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+7369minor)pagefaults 0swaps
and that "half a second" vs "five seconds" difference is really
noticeable.
Right now I do "git grep" as a random "ok, where was it", and it works
very well, because it's basically instantaneous. And the difference
between "instantaneous" and "5 seconds" is very big (the five seconds is
also long enough that the CPU fan comes on on my G5, which is my sign of
"too much work for the CPU".
I haven't looked at _why_ the builtin grep is ten times slower. I suspect
it's just the regexp library being a lot slower than the external
optimized grep, but it may also be just overhead (it looks, for example,
like the builtin grep does all matches just one line at a time. And it
actually reads the file in, when mmap might be more efficient, I dunno).
Regardless, it's a huge downer.
Linus
^ permalink raw reply
* Re: [RFC] qgit with tabs
From: Marco Costalba @ 2006-05-13 22:38 UTC (permalink / raw)
To: Pavel Roskin; +Cc: git
In-Reply-To: <20060513142840.39c0kwkw84g8g88g@webmail.spamcop.net>
Hi Pavel,
>
> Sure, but I often want to see what changed in a particular file.
>
> And of course I only mean the subwindow dislaying the files affected by the
> patch. The file tree should still have file annotation bound to the double
> click.
>
I understand your reasons, but I have some doubts about this change:
1) The context menu is currently shared between the tree and the file
list, splitting in two subcases adds some crap to the code (ok, this
is not the real doubt ;-) )
2) The context menu is currently shared between the file list in main
view and the file list in patch view. The file list in patch view, of
course, does not need a double click, a single click is enough to
select corresponding file's diff. In main view you currently need a
single click _plus_ a 'p' key press to change the view. So we should
add another subcase here.
3) It is true that double clicking on a revision switch to the patch
view at top position (if no file is selected), but it's also true that
you can select the file's related diff directly in patch view with a
single click on the right column file list.
4) Once a file is selected, as example with a single click, you can
browse through rev list and the selection is preserved, it means that
anytime you switch to patch view page the content will be _already_
centered on the correct diff.
5) Double clicking on a file name is currently the only way (without
opening the menu) to show the file content tab, with your suggested
change we will have two ways to switch to patch view and no one to
switch to file view.
6) Selecting from the tree view is very slow if you have to search for
the correct file, it is fast only if the file is already selected, but
in this case is faster to press 'p' key ;-)
Marco
^ permalink raw reply
* Re: git diff: support "-U" and "--unified" options properly
From: Junio C Hamano @ 2006-05-13 21:22 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0605131404391.3866@g5.osdl.org>
Linus Torvalds <torvalds@osdl.org> writes:
> On Sat, 13 May 2006, Junio C Hamano wrote:
>>
>> Linus Torvalds <torvalds@osdl.org> writes:
>>
>> > [ Maybe this can still hit 1.3.3? ]
>>
>> Ah, we did not pass the diffopt to the function builtin_diff() in
>> 1.3.X series, so not really.
>
> Ahh, ok. Never mind. It's not like people have been clamoring for it, it
> just seemed to be such a _silly_ thing.
>
> Might as well just go into the curren development tree, and then we'll
> have it fixed eventually (1.4.0?)
No question about that part. I've been meaning to start drawing
the line of what to have in 1.4 and what to leave out, but the
last week was shot so I haven't got around to.
A rough outline.
I'd like to have the following topics from "next":
* cvsserver and cvsexportcommit updates (ml/cvs)
Ready.
* config syntax (lt/config)
Ready.
* built-in grep (jc/grep)
Ready.
* built-in format-patch (js/fmt-patch)
Some features are still missing compared to the script
version.
* remotes/ information from .git/config (js/fetchconfig)
This by itself is more or less ready, but I would like to
further adjust it to the "per branch configuration"
discussion before pushing it out.
I'd like to eventually arrange things like this.
[branch "master"]
remote = "ko-private"
; prevent "reset --hard" from rewinding past this.
rewind-barrier = refs/heads/ko-master
; my private build areas on the kernel.org machines
[remote "ko-private"]
url = "x86-64-build.kernel.org:git"
url = "i386-build.kernel.org:git"
push = master:origin
push = next:next
push = +pu:pu
push = maint:maint
; for publishing and keeping track of what I pushed there last time
[remote "ko"]
url = "kernel.org:/pub/scm/git/git.git"
push = master:master
push = next:next
push = +pu:pu
push = maint:maint
fetch = master:ko-master
fetch = next:ko-next
fetch = +pu:ko-pu
fetch = maint:ko-maint
^ permalink raw reply
* [RFC] Add "rcs format diff" support
From: Linus Torvalds @ 2006-05-13 21:14 UTC (permalink / raw)
To: Junio C Hamano, Git Mailing List; +Cc: Al Viro, Davide Libenzi
Al was asking for the "diff -n" format, which is the old RCS format, and
which is really easy to parse.
Now, we can't use the "-n" flag, because we use that for something else,
and quite frankly, I don't know what to do about the diff _header_ (RCS
format doesn't have a header, afaik), but this implements the actual core
"xdiff" rcs-format patch emit logic, and exposes it with the
XDL_EMIT_RCSFORMAT flag.
(In order to get valid diffs, you also have to set the context to zero
when you set the RCSFORMAT flag).
It also adds a "--rcs-format" flag to the git diff option parsing, so you
can test it out, but as mentioned, we will still emit the full git header.
Davide - I think the "xdiff/" sub-part of the patch should apply fine to
the standard xdiff sources, but I'm not sure you're really interested. The
header issue doesn't matter there, of course, since xdiff doesn't output
any headers (ie that is an issue for the higher-level user).
The biggest issue for the xdiff library was that I needed to pass down
the xecfg parameter deeper into the call-chain (ie down to xdl_emit_record
& co). The rest is pretty trivial.
Al - feel free to play with this. I didn't test it heavily, but it gave
the right output for the one case I compared with "diff -n". This patch is
on top of my previous patch to parse "-U" and "--unified".
Junio - this is not really meant for applying, although I don't think
there is any real down-side to this either.
Linus
---
diff --git a/diff.c b/diff.c
index be925a3..fd8f454 100644
--- a/diff.c
+++ b/diff.c
@@ -568,6 +568,10 @@ static void builtin_diff(const char *nam
xecfg.ctxlen = strtoul(diffopts + 2, NULL, 10);
ecb.outf = fn_out;
ecb.priv = &ecbdata;
+ if (o->rcs_format) {
+ xecfg.flags |= XDL_EMIT_RCSFORMAT;
+ xecfg.ctxlen = 0;
+ }
xdl_diff(&mf1, &mf2, &xpp, &xecfg, &ecb);
}
@@ -1277,6 +1281,8 @@ int diff_opt_parse(struct diff_options *
options->output_format = DIFF_FORMAT_PATCH;
else if (opt_arg(arg, 'U', "unified", &options->context))
options->output_format = DIFF_FORMAT_PATCH;
+ else if (!strcmp(arg, "--rcs-format"))
+ options->rcs_format = 1;
else if (!strcmp(arg, "--patch-with-raw")) {
options->output_format = DIFF_FORMAT_PATCH;
options->with_raw = 1;
diff --git a/diff.h b/diff.h
index bef586d..953beb9 100644
--- a/diff.h
+++ b/diff.h
@@ -29,6 +29,7 @@ struct diff_options {
with_stat:1,
tree_in_recursive:1,
binary:1,
+ rcs_format:1,
full_index:1,
silent_on_remove:1,
find_copies_harder:1;
diff --git a/xdiff/xdiff.h b/xdiff/xdiff.h
index 2540e8a..a52359e 100644
--- a/xdiff/xdiff.h
+++ b/xdiff/xdiff.h
@@ -36,6 +36,7 @@ #define XDL_PATCH_MODEMASK ((1 << 8) - 1
#define XDL_PATCH_IGNOREBSPACE (1 << 8)
#define XDL_EMIT_FUNCNAMES (1 << 0)
+#define XDL_EMIT_RCSFORMAT (1 << 1)
#define XDL_MMB_READONLY (1 << 0)
diff --git a/xdiff/xemit.c b/xdiff/xemit.c
index ad5bfb1..e127469 100644
--- a/xdiff/xemit.c
+++ b/xdiff/xemit.c
@@ -26,7 +26,7 @@ #include "xinclude.h"
static long xdl_get_rec(xdfile_t *xdf, long ri, char const **rec);
-static int xdl_emit_record(xdfile_t *xdf, long ri, char const *pre, xdemitcb_t *ecb);
+static int xdl_emit_record(xdfile_t *xdf, long ri, char const *pre, xdemitcb_t *ecb, xdemitconf_t const *xecfg);
static xdchange_t *xdl_get_hunk(xdchange_t *xscr, xdemitconf_t const *xecfg);
@@ -40,12 +40,13 @@ static long xdl_get_rec(xdfile_t *xdf, l
}
-static int xdl_emit_record(xdfile_t *xdf, long ri, char const *pre, xdemitcb_t *ecb) {
+static int xdl_emit_record(xdfile_t *xdf, long ri, char const *pre,
+ xdemitcb_t *ecb, xdemitconf_t const *xecfg) {
long size, psize = strlen(pre);
char const *rec;
size = xdl_get_rec(xdf, ri, &rec);
- if (xdl_emit_diffrec(rec, size, pre, psize, ecb) < 0) {
+ if (xdl_emit_diffrec(rec, size, pre, psize, ecb, xecfg) < 0) {
return -1;
}
@@ -129,14 +130,14 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange
sizeof(funcbuf), &funclen);
}
if (xdl_emit_hunk_hdr(s1 + 1, e1 - s1, s2 + 1, e2 - s2,
- funcbuf, funclen, ecb) < 0)
+ funcbuf, funclen, ecb, xecfg) < 0)
return -1;
/*
* Emit pre-context.
*/
for (; s1 < xch->i1; s1++)
- if (xdl_emit_record(&xe->xdf1, s1, " ", ecb) < 0)
+ if (xdl_emit_record(&xe->xdf1, s1, " ", ecb, xecfg) < 0)
return -1;
for (s1 = xch->i1, s2 = xch->i2;; xch = xch->next) {
@@ -144,21 +145,21 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange
* Merge previous with current change atom.
*/
for (; s1 < xch->i1 && s2 < xch->i2; s1++, s2++)
- if (xdl_emit_record(&xe->xdf1, s1, " ", ecb) < 0)
+ if (xdl_emit_record(&xe->xdf1, s1, " ", ecb, xecfg) < 0)
return -1;
/*
* Removes lines from the first file.
*/
for (s1 = xch->i1; s1 < xch->i1 + xch->chg1; s1++)
- if (xdl_emit_record(&xe->xdf1, s1, "-", ecb) < 0)
+ if (xdl_emit_record(&xe->xdf1, s1, "-", ecb, xecfg) < 0)
return -1;
/*
* Adds lines from the second file.
*/
for (s2 = xch->i2; s2 < xch->i2 + xch->chg2; s2++)
- if (xdl_emit_record(&xe->xdf2, s2, "+", ecb) < 0)
+ if (xdl_emit_record(&xe->xdf2, s2, "+", ecb, xecfg) < 0)
return -1;
if (xch == xche)
@@ -171,7 +172,7 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange
* Emit post-context.
*/
for (s1 = xche->i1 + xche->chg1; s1 < e1; s1++)
- if (xdl_emit_record(&xe->xdf1, s1, " ", ecb) < 0)
+ if (xdl_emit_record(&xe->xdf1, s1, " ", ecb, xecfg) < 0)
return -1;
}
diff --git a/xdiff/xutils.c b/xdiff/xutils.c
index 21ab8e7..b0d075a 100644
--- a/xdiff/xutils.c
+++ b/xdiff/xutils.c
@@ -43,10 +43,20 @@ long xdl_bogosqrt(long n) {
int xdl_emit_diffrec(char const *rec, long size, char const *pre, long psize,
- xdemitcb_t *ecb) {
+ xdemitcb_t *ecb, xdemitconf_t const *xecfg) {
mmbuffer_t mb[3];
int i;
+ if (xecfg->flags & XDL_EMIT_RCSFORMAT) {
+ if (*pre != '+')
+ return 0;
+ mb[0].ptr = (char *) rec;
+ mb[0].size = size;
+ if (ecb->outf(ecb->priv, mb, 1) < 0)
+ return -1;
+ return 0;
+ }
+
mb[0].ptr = (char *) pre;
mb[0].size = psize;
mb[1].ptr = (char *) rec;
@@ -249,11 +259,34 @@ long xdl_atol(char const *str, char cons
int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2,
- const char *func, long funclen, xdemitcb_t *ecb) {
+ const char *func, long funclen,
+ xdemitcb_t *ecb, xdemitconf_t const *xecfg) {
int nb = 0;
mmbuffer_t mb;
char buf[128];
+ if (xecfg->flags & XDL_EMIT_RCSFORMAT) {
+ if (c1) {
+ buf[nb++] = 'd';
+ nb += xdl_num_out(buf + nb, s1);
+ buf[nb++] = ' ';
+ nb += xdl_num_out(buf + nb, c1);
+ buf[nb++] = '\n';
+ }
+ if (c2) {
+ buf[nb++] = 'a';
+ nb += xdl_num_out(buf + nb, s2);
+ buf[nb++] = ' ';
+ nb += xdl_num_out(buf + nb, c2);
+ buf[nb++] = '\n';
+ }
+ mb.ptr = buf;
+ mb.size = nb;
+ if (ecb->outf(ecb->priv, &mb, 1) < 0)
+ return -1;
+ return 0;
+ }
+
memcpy(buf, "@@ -", 4);
nb += 4;
diff --git a/xdiff/xutils.h b/xdiff/xutils.h
index ea38ee9..e5c6ed0 100644
--- a/xdiff/xutils.h
+++ b/xdiff/xutils.h
@@ -26,7 +26,7 @@ #define XUTILS_H
long xdl_bogosqrt(long n);
int xdl_emit_diffrec(char const *rec, long size, char const *pre, long psize,
- xdemitcb_t *ecb);
+ xdemitcb_t *ecb, xdemitconf_t const *xecfg);
int xdl_cha_init(chastore_t *cha, long isize, long icount);
void xdl_cha_free(chastore_t *cha);
void *xdl_cha_alloc(chastore_t *cha);
@@ -38,7 +38,8 @@ unsigned int xdl_hashbits(unsigned int s
int xdl_num_out(char *out, long val);
long xdl_atol(char const *str, char const **next);
int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2,
- const char *func, long funclen, xdemitcb_t *ecb);
+ const char *func, long funclen,
+ xdemitcb_t *ecb, xdemitconf_t const *xecfg);
^ permalink raw reply related
* Re: git diff: support "-U" and "--unified" options properly
From: Linus Torvalds @ 2006-05-13 21:05 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Git Mailing List
In-Reply-To: <7vzmhlsksm.fsf@assigned-by-dhcp.cox.net>
On Sat, 13 May 2006, Junio C Hamano wrote:
>
> Linus Torvalds <torvalds@osdl.org> writes:
>
> > [ Maybe this can still hit 1.3.3? ]
>
> Ah, we did not pass the diffopt to the function builtin_diff() in
> 1.3.X series, so not really.
Ahh, ok. Never mind. It's not like people have been clamoring for it, it
just seemed to be such a _silly_ thing.
Might as well just go into the curren development tree, and then we'll
have it fixed eventually (1.4.0?)
Linus
^ permalink raw reply
* Re: git diff: support "-U" and "--unified" options properly
From: Junio C Hamano @ 2006-05-13 20:59 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0605131317200.3866@g5.osdl.org>
Linus Torvalds <torvalds@osdl.org> writes:
> [ Maybe this can still hit 1.3.3? ]
Ah, we did not pass the diffopt to the function builtin_diff() in
1.3.X series, so not really. We could forward port but I do not
know if it is worth the effort of backporting while stripping
the updates of the whole chain of diff generation from the post
1.3.0 "master" work. I have to think a bit.
^ permalink raw reply
* Re: git diff: support "-U" and "--unified" options properly
From: Junio C Hamano @ 2006-05-13 20:30 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0605131317200.3866@g5.osdl.org>
Linus Torvalds <torvalds@osdl.org> writes:
> We used to parse "-U" and "--unified" as part of the GIT_DIFF_OPTS
> environment variable, but strangely enough we would _not_ parse them as
> part of the normal diff command line (where we only accepted "-u").
>
> This adds parsing of -U and --unified, both with an optional numeric
> argument. So now you can just say
>
> git diff --unified=5
>
> [ Maybe this can still hit 1.3.3? ]
I think so.
^ permalink raw reply
* git diff: support "-U" and "--unified" options properly
From: Linus Torvalds @ 2006-05-13 20:23 UTC (permalink / raw)
To: Junio C Hamano, Git Mailing List
We used to parse "-U" and "--unified" as part of the GIT_DIFF_OPTS
environment variable, but strangely enough we would _not_ parse them as
part of the normal diff command line (where we only accepted "-u").
This adds parsing of -U and --unified, both with an optional numeric
argument. So now you can just say
git diff --unified=5
to get a unified diff with a five-line context, instead of having to do
something silly like
GIT_DIFF_OPTS="--unified=5" git diff -u
(that silly format does continue to still work, of course).
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
---
[ Maybe this can still hit 1.3.3? ]
diff --git a/combine-diff.c b/combine-diff.c
index 8a8fe38..64b20cc 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -608,6 +608,7 @@ static int show_patch_diff(struct combin
int abbrev = opt->full_index ? 40 : DEFAULT_ABBREV;
mmfile_t result_file;
+ context = opt->context;
/* Read the result of merge first */
if (!working_tree_file)
result = grab_blob(elem->sha1, &result_size);
diff --git a/diff.c b/diff.c
index 7a7b839..be925a3 100644
--- a/diff.c
+++ b/diff.c
@@ -558,7 +558,7 @@ static void builtin_diff(const char *nam
ecbdata.label_path = lbl;
xpp.flags = XDF_NEED_MINIMAL;
- xecfg.ctxlen = 3;
+ xecfg.ctxlen = o->context;
xecfg.flags = XDL_EMIT_FUNCNAMES;
if (!diffopts)
;
@@ -1182,6 +1182,7 @@ void diff_setup(struct diff_options *opt
options->line_termination = '\n';
options->break_opt = -1;
options->rename_limit = -1;
+ options->context = 3;
options->change = diff_change;
options->add_remove = diff_addremove;
@@ -1222,11 +1223,60 @@ int diff_setup_done(struct diff_options
return 0;
}
+int opt_arg(const char *arg, int arg_short, const char *arg_long, int *val)
+{
+ char c, *eq;
+ int len;
+
+ if (*arg != '-')
+ return 0;
+ c = *++arg;
+ if (!c)
+ return 0;
+ if (c == arg_short) {
+ c = *++arg;
+ if (!c)
+ return 1;
+ if (val && isdigit(c)) {
+ char *end;
+ int n = strtoul(arg, &end, 10);
+ if (*end)
+ return 0;
+ *val = n;
+ return 1;
+ }
+ return 0;
+ }
+ if (c != '-')
+ return 0;
+ arg++;
+ eq = strchr(arg, '=');
+ if (eq)
+ len = eq - arg;
+ else
+ len = strlen(arg);
+ if (!len || strncmp(arg, arg_long, len))
+ return 0;
+ if (eq) {
+ int n;
+ char *end;
+ if (!isdigit(*++eq))
+ return 0;
+ n = strtoul(eq, &end, 10);
+ if (*end)
+ return 0;
+ *val = n;
+ }
+ return 1;
+}
+
int diff_opt_parse(struct diff_options *options, const char **av, int ac)
{
const char *arg = av[0];
if (!strcmp(arg, "-p") || !strcmp(arg, "-u"))
options->output_format = DIFF_FORMAT_PATCH;
+ else if (opt_arg(arg, 'U', "unified", &options->context))
+ options->output_format = DIFF_FORMAT_PATCH;
else if (!strcmp(arg, "--patch-with-raw")) {
options->output_format = DIFF_FORMAT_PATCH;
options->with_raw = 1;
diff --git a/diff.h b/diff.h
index d052608..bef586d 100644
--- a/diff.h
+++ b/diff.h
@@ -32,6 +32,7 @@ struct diff_options {
full_index:1,
silent_on_remove:1,
find_copies_harder:1;
+ int context;
int break_opt;
int detect_rename;
int line_termination;
^ permalink raw reply related
* Re: [RFC] qgit with tabs
From: Pavel Roskin @ 2006-05-13 18:28 UTC (permalink / raw)
To: Marco Costalba; +Cc: git
In-Reply-To: <e5bfff550605130431w417b8aacl2b17cf5655b46f31@mail.gmail.com>
Quoting Marco Costalba <mcostalba@gmail.com>:
> > Just one thing for now. Double click on a file on the "rev list" tab
> should
> > show the patch (what Ctrl-P would do), not the whole file. That would be
> more
> > compatible with gitk, and it's what I normally need if I just browse the
> latest
> > changes in the rev list.
> >
>
> Well, double click activates the current top entry in context menu.
That's a good thing. But I think that the top entry should be different.
> This behaviour has not changed from past releases.
I know. But as the more prominent issues are sorted out, minor things become
more visible.
> To show the patch
> perhaps you may, as always, double click on the selected revision, in
> revisions list.
Sure, but I often want to see what changed in a particular file.
And of course I only mean the subwindow dislaying the files affected by the
patch. The file tree should still have file annotation bound to the double
click.
> FWIK gitk does not have a file content viewer.
That's true. The reason may be because changes are more interesing than the
whole file in the context of git (as opposed to the context of an editor or a
compiler).
--
Regards,
Pavel Roskin
^ permalink raw reply
* Re: Tracking branch history
From: Shawn Pearce @ 2006-05-13 18:18 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Linus Torvalds, git
In-Reply-To: <7vbqu1vps3.fsf@assigned-by-dhcp.cox.net>
Junio C Hamano <junkio@cox.net> wrote:
> Linus Torvalds <torvalds@osdl.org> writes:
>
> > I actually disagree with Junio - I think the logging the name made sense.
> > If you have a shared repo with multiple people pushing to the same branch,
> > it's interesting to see who does the pushing.
>
> Yes, I agree recording that information is interesting.
>
> My comment was about how it is recorded. In the local case
> GIT_COMMITTER_IDENT is what you want as Shawn did in his
> original proposal, but remote "pushing into shared repository"
> case I do not think it is available in general.
>
> Well, at least that was what I was thinking when I made that
> comment. However,
>
> If the pushers arrange to have appropriate environment variables
> while receive-pack does its work (.git/config in the target
> repository is not an appropriate place to get user.* settings
> from in a shared setting), what you say makes perfect sense.
>
> Having the usual enviornment available would be handy to make
> the hooks on the receiving end to do useful things anyway, so I
> retract that suggestion.
>
> > I also think it might be good to save the oldsha1 value. Yes, it _should_
> > always be the previous sha1 logged, but it's interesting to see in case it
> > isn't (ie the ref was updated some other way), and it's also interesting
> > for the first entry after logging has been enabled.
> >
> > Linue
>
> Yes, and also what user-level command was used to cause update
> the ref; was it a merge from remote, own commit, rewind/rebase?
>
> Junia
>
> ;-)
>
New version of the patch below; this patch superceeds the prior two.
The format now includes the old sha1 and committer ident, and does
not write a log record if the update-ref is pointless.
Hmm, why does update-ref do a pointless update?
Now the problem with this patch is it doesn't append to the log
in the case of upload-pack or fetch; nor does it record what user
level command caused the update.
[spearce@pb15 git]$ grep update-ref *.sh *.perl *.py | wc -l
20
Hmm. That's easy enough to fix. Anyone up for a '-m foo' comment
switch to update-ref from the higher-level tools such that foo
appears as part of the log line?
I'll be offline for a few hours but can work on this some more
later tonight.
--> -
Log ref updates to logs/refs/<ref>
If config parameter core.logRefUpdates is true then append a line
to .git/logs/refs/<ref> whenever git-update-ref <ref> is executed.
Each log line contains the following information:
oldsha1 <SP> newsha1 <SP> committer <LF>
where committer is the current user, date, time and timezone in
the standard GIT ident format. If the caller is unable to append
to the log file then git-update-ref will fail without updating <ref>.
---
Documentation/config.txt | 7 ++++++
Documentation/git-update-ref.txt | 19 +++++++++++++++
cache.h | 1 +
config.c | 5 ++++
environment.c | 1 +
update-ref.c | 48 ++++++++++++++++++++++++++++++++++++--
6 files changed, 78 insertions(+), 3 deletions(-)
898e33d9c2def73296697d65dff0676d96adb5d8
diff --git a/Documentation/config.txt b/Documentation/config.txt
index d1a4bec..f06695c 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -70,6 +70,13 @@ core.preferSymlinkRefs::
This is sometimes needed to work with old scripts that
expect HEAD to be a symbolic link.
+core.logRefUpdates::
+ If true, `git-update-ref` will append a line to
+ "$GIT_DIR/logs/<ref>" listing the new SHA1 and the date/time
+ of the update. This information can be used to determine
+ what commit was the tip of a branch "2 days ago". This value
+ is false by default (no logging).
+
core.repositoryFormatVersion::
Internal variable identifying the repository format and layout
version.
diff --git a/Documentation/git-update-ref.txt b/Documentation/git-update-ref.txt
index 475237f..edd39d3 100644
--- a/Documentation/git-update-ref.txt
+++ b/Documentation/git-update-ref.txt
@@ -49,6 +49,25 @@ for reading but not for writing (so we'l
ref symlink to some other tree, if you have copied a whole
archive by creating a symlink tree).
+Logging Updates
+---------------
+If config parameter "core.logRefUpdates" is true then
+`git-update-ref` will append a line to the log file
+"$GIT_DIR/logs/<ref>" (dereferencing all symbolic refs before
+creating the log name) describing the change in ref value. Log lines
+are formatted as:
+
+ . oldsha1 SP newsha1 SP committer LF
++
+Where "oldsha1" is the 40 character hexadecimal value previously
+stored in <ref>, "newsha1" is the 40 character hexadecimal value of
+<newvalue> and "committer" is the committer's name, email address
+and date in the standard GIT committer ident format.
+
+An update will fail (without changing <ref>) if the current user is
+unable to create a new log file, append to the existing log file
+or does not have committer information available.
+
Author
------
Written by Linus Torvalds <torvalds@osdl.org>.
diff --git a/cache.h b/cache.h
index b1300cd..887ce20 100644
--- a/cache.h
+++ b/cache.h
@@ -171,6 +171,7 @@ extern void rollback_index_file(struct c
extern int trust_executable_bit;
extern int assume_unchanged;
extern int prefer_symlink_refs;
+extern int log_ref_updates;
extern int warn_ambiguous_refs;
extern int diff_rename_limit_default;
extern int shared_repository;
diff --git a/config.c b/config.c
index 0f518c9..f8a814e 100644
--- a/config.c
+++ b/config.c
@@ -232,6 +232,11 @@ int git_default_config(const char *var,
return 0;
}
+ if (!strcmp(var, "core.logrefupdates")) {
+ log_ref_updates = git_config_bool(var, value);
+ return 0;
+ }
+
if (!strcmp(var, "core.warnambiguousrefs")) {
warn_ambiguous_refs = git_config_bool(var, value);
return 0;
diff --git a/environment.c b/environment.c
index 444c99e..437266e 100644
--- a/environment.c
+++ b/environment.c
@@ -14,6 +14,7 @@ char git_default_name[MAX_GITNAME];
int trust_executable_bit = 1;
int assume_unchanged = 0;
int prefer_symlink_refs = 0;
+int log_ref_updates = 0;
int warn_ambiguous_refs = 1;
int repository_format_version = 0;
char git_commit_encoding[MAX_ENCODING_LENGTH] = "utf-8";
diff --git a/update-ref.c b/update-ref.c
index fd48742..64fc3db 100644
--- a/update-ref.c
+++ b/update-ref.c
@@ -22,7 +22,7 @@ int main(int argc, char **argv)
const char *refname, *value, *oldval, *path;
char *lockpath;
unsigned char sha1[20], oldsha1[20], currsha1[20];
- int fd, written;
+ int fd, written, pfxlen;
setup_git_directory();
git_config(git_default_config);
@@ -38,7 +38,9 @@ int main(int argc, char **argv)
if (oldval && get_sha1(oldval, oldsha1))
die("%s: not a valid old SHA1", oldval);
- path = resolve_ref(git_path("%s", refname), currsha1, !!oldval);
+ path = git_path("%s", refname);
+ pfxlen = strlen(path) - strlen(refname);
+ path = resolve_ref(path, currsha1, !!oldval);
if (!path)
die("No such ref: %s", refname);
@@ -50,7 +52,7 @@ int main(int argc, char **argv)
exit(0);
}
path = strdup(path);
- lockpath = mkpath("%s.lock", path);
+ lockpath = strdup(mkpath("%s.lock", path));
if (safe_create_leading_directories(lockpath) < 0)
die("Unable to create all of %s", lockpath);
@@ -75,6 +77,46 @@ int main(int argc, char **argv)
}
/*
+ * Write to the log if logging of ref updates is enabled
+ */
+ if (log_ref_updates && memcmp(currsha1, sha1, 20)) {
+ char *logrec, *logpath;
+ const char *comitter;
+ unsigned maxlen, len;
+ int logfd;
+
+ setup_ident();
+ comitter = git_committer_info(1);
+ maxlen = strlen(comitter) + 2*40 + 4;
+ logrec = xmalloc(maxlen);
+ len = snprintf(logrec, maxlen, "%s %s %s\n",
+ sha1_to_hex(currsha1),
+ sha1_to_hex(sha1),
+ comitter);
+ if (len >= maxlen) {
+ unlink(lockpath);
+ die("Internal error formatting log record.");
+ }
+
+ logpath = git_path("logs/%s", path + pfxlen);
+ if (safe_create_leading_directories(logpath) < 0) {
+ unlink(lockpath);
+ die("Unable to create all of %s", logpath);
+ }
+ logfd = open(logpath, O_CREAT | O_APPEND | O_WRONLY, 0666);
+ if (logfd < 0) {
+ unlink(lockpath);
+ die("Unable to append to %s", logpath);
+ }
+ written = write(logfd, logrec, len);
+ if (written != len) {
+ unlink(lockpath);
+ die("Unable to append to %s", logpath);
+ }
+ close(logfd);
+ }
+
+ /*
* Finally, replace the old ref with the new one
*/
if (rename(lockpath, path) < 0) {
--
1.3.2.g7278
^ permalink raw reply related
* Re: [PATCH] Add "--branches" and "--tags" options to git-rev-parse.
From: Junio C Hamano @ 2006-05-13 17:38 UTC (permalink / raw)
To: Sean Estabrooks; +Cc: git
In-Reply-To: <BAYC1-PASMTP0299DC98A51B55188BDF96AEAD0@CEZ.ICE>
Sean Estabrooks <seanlkml@sympatico.ca> writes:
> "git branch" uses rev-parse and can become slow when there are many
> tags. Use the new "--branches" option of rev-parse to speed things up.
Makes sense perhaps.
I understand you added --tags for completeness. Probably it
would make sense to add --remotes if you are shooting for that.
^ permalink raw reply
* Re: daily git packages for debian etch and sarge
From: Junio C Hamano @ 2006-05-13 17:31 UTC (permalink / raw)
To: Jakub Narebski; +Cc: git
In-Reply-To: <e44jji$bmf$1@sea.gmane.org>
Jakub Narebski <jnareb@gmail.com> writes:
> Thomas Glanzmann wrote:
>
>> is there someone who builds and publishes daily automatic git packages
>> of Junios tree for debian sarge / etch (testing)?
>
> http://git.or.cz/download.html
Excuse me, where is the deb package link to daily automatic
build results on that page?
^ permalink raw reply
* Re: Tracking branch history
From: Junio C Hamano @ 2006-05-13 16:43 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Shawn Pearce, git
In-Reply-To: <Pine.LNX.4.64.0605130815550.3866@g5.osdl.org>
Linus Torvalds <torvalds@osdl.org> writes:
> I actually disagree with Junio - I think the logging the name made sense.
> If you have a shared repo with multiple people pushing to the same branch,
> it's interesting to see who does the pushing.
Yes, I agree recording that information is interesting.
My comment was about how it is recorded. In the local case
GIT_COMMITTER_IDENT is what you want as Shawn did in his
original proposal, but remote "pushing into shared repository"
case I do not think it is available in general.
Well, at least that was what I was thinking when I made that
comment. However,
If the pushers arrange to have appropriate environment variables
while receive-pack does its work (.git/config in the target
repository is not an appropriate place to get user.* settings
from in a shared setting), what you say makes perfect sense.
Having the usual enviornment available would be handy to make
the hooks on the receiving end to do useful things anyway, so I
retract that suggestion.
> I also think it might be good to save the oldsha1 value. Yes, it _should_
> always be the previous sha1 logged, but it's interesting to see in case it
> isn't (ie the ref was updated some other way), and it's also interesting
> for the first entry after logging has been enabled.
>
> Linue
Yes, and also what user-level command was used to cause update
the ref; was it a merge from remote, own commit, rewind/rebase?
Junia
;-)
^ permalink raw reply
* Re: Tracking branch history
From: Linus Torvalds @ 2006-05-13 15:20 UTC (permalink / raw)
To: Shawn Pearce; +Cc: Junio C Hamano, git
In-Reply-To: <20060513074328.GB21998@spearce.org>
On Sat, 13 May 2006, Shawn Pearce wrote:
>
> Forget my last patch. This one automatically creates the log file
> by looking for a config value of 'core.logRefUpdates=true'.
Looks better.
I actually disagree with Junio - I think the logging the name made sense.
If you have a shared repo with multiple people pushing to the same branch,
it's interesting to see who does the pushing.
I also think it might be good to save the oldsha1 value. Yes, it _should_
always be the previous sha1 logged, but it's interesting to see in case it
isn't (ie the ref was updated some other way), and it's also interesting
for the first entry after logging has been enabled.
Hmm?
Linue
^ permalink raw reply
* [PATCH] Add "--branches" and "--tags" options to git-rev-parse.
From: Sean Estabrooks @ 2006-05-13 15:13 UTC (permalink / raw)
To: git
"git branch" uses rev-parse and can become slow when there are many
tags. Use the new "--branches" option of rev-parse to speed things up.
Signed-off-by: Sean Estabrooks <seanlkml@sympatico.ca>
---
Documentation/git-rev-parse.txt | 6 ++++++
git-branch.sh | 3 +--
refs.c | 18 ++++++++++++++----
refs.h | 2 ++
rev-parse.c | 8 ++++++++
5 files changed, 31 insertions(+), 6 deletions(-)
7898e1e58b18e992e3d90516fc9e6f3476a385ed
diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt
index 8b95df0..c1da2bf 100644
--- a/Documentation/git-rev-parse.txt
+++ b/Documentation/git-rev-parse.txt
@@ -67,6 +67,12 @@ OPTIONS
--all::
Show all refs found in `$GIT_DIR/refs`.
+--branches::
+ Show branch refs found in `$GIT_DIR/refs/heads`.
+
+--tags::
+ Show tag refs found in `$GIT_DIR/refs/tags`.
+
--show-prefix::
When the command is invoked from a subdirectory, show the
path of the current directory relative to the top-level
diff --git a/git-branch.sh b/git-branch.sh
index ebcc898..134e68c 100755
--- a/git-branch.sh
+++ b/git-branch.sh
@@ -82,8 +82,7 @@ done
case "$#" in
0)
- git-rev-parse --symbolic --all |
- sed -ne 's|^refs/heads/||p' |
+ git-rev-parse --symbolic --branches |
sort |
while read ref
do
diff --git a/refs.c b/refs.c
index 275b914..9c29a73 100644
--- a/refs.c
+++ b/refs.c
@@ -114,7 +114,7 @@ int read_ref(const char *filename, unsig
return -1;
}
-static int do_for_each_ref(const char *base, int (*fn)(const char *path, const unsigned char *sha1))
+static int do_for_each_ref(const char *base, int (*fn)(const char *path, const unsigned char *sha1), int trim)
{
int retval = 0;
DIR *dir = opendir(git_path("%s", base));
@@ -146,7 +146,7 @@ static int do_for_each_ref(const char *b
if (stat(git_path("%s", path), &st) < 0)
continue;
if (S_ISDIR(st.st_mode)) {
- retval = do_for_each_ref(path, fn);
+ retval = do_for_each_ref(path, fn, trim);
if (retval)
break;
continue;
@@ -160,7 +160,7 @@ static int do_for_each_ref(const char *b
"commit object!", path);
continue;
}
- retval = fn(path, sha1);
+ retval = fn(path + trim, sha1);
if (retval)
break;
}
@@ -180,7 +180,17 @@ int head_ref(int (*fn)(const char *path,
int for_each_ref(int (*fn)(const char *path, const unsigned char *sha1))
{
- return do_for_each_ref("refs", fn);
+ return do_for_each_ref("refs", fn, 0);
+}
+
+int for_each_tag(int (*fn)(const char *path, const unsigned char *sha1))
+{
+ return do_for_each_ref("refs/tags", fn, 10);
+}
+
+int for_each_branch(int (*fn)(const char *path, const unsigned char *sha1))
+{
+ return do_for_each_ref("refs/heads", fn, 11);
}
static char *ref_file_name(const char *ref)
diff --git a/refs.h b/refs.h
index 2625596..f270b62 100644
--- a/refs.h
+++ b/refs.h
@@ -7,6 +7,8 @@ #define REFS_H
*/
extern int head_ref(int (*fn)(const char *path, const unsigned char *sha1));
extern int for_each_ref(int (*fn)(const char *path, const unsigned char *sha1));
+extern int for_each_tag(int (*fn)(const char *path, const unsigned char *sha1));
+extern int for_each_branch(int (*fn)(const char *path, const unsigned char *sha1));
/** Reads the refs file specified into sha1 **/
extern int get_ref_sha1(const char *ref, unsigned char *sha1);
diff --git a/rev-parse.c b/rev-parse.c
index 62e16af..4eb38de 100644
--- a/rev-parse.c
+++ b/rev-parse.c
@@ -255,6 +255,14 @@ int main(int argc, char **argv)
for_each_ref(show_reference);
continue;
}
+ if (!strcmp(arg, "--branches")) {
+ for_each_branch(show_reference);
+ continue;
+ }
+ if (!strcmp(arg, "--tags")) {
+ for_each_tag(show_reference);
+ continue;
+ }
if (!strcmp(arg, "--show-prefix")) {
if (prefix)
puts(prefix);
--
1.3.2.g419f
^ permalink raw reply related
* Re: Tracking branch history
From: Linus Torvalds @ 2006-05-13 15:11 UTC (permalink / raw)
To: Shawn Pearce; +Cc: Junio C Hamano, git
In-Reply-To: <20060513071753.GA21998@spearce.org>
On Sat, 13 May 2006, Shawn Pearce wrote:
>
> +
> + /*
> + * If logging is required make sure we can append to the log.
> + */
> + logpath = strdup(git_path("logs/%s", path + pfxlen));
I don't think you need the strdup().
I also think you might as well just let the logging silently fail, but
hey, that's up to you.
Linus
^ permalink raw reply
* Re: Tracking branch history
From: Elrond @ 2006-05-13 12:53 UTC (permalink / raw)
To: git
In-Reply-To: <Pine.LNX.4.64.0605121838490.6713@iabervon.org>
Daniel Barkalow <barkalow <at> iabervon.org> writes:
>
> One feature that might make git more intuitive to people is if we were to
> additionally track the history of what commit was the head of each branch
> over time. This is only vaguely related to the history of the content, but
> it's well-defined and sometimes significant.
>
> E.g., if you know that two weeks ago, what you had worked, but it doesn't
> work now, you can use git-bisect to figure out what happened, but first
> you have to figure out what commit it was that you were using two weeks
> ago. Two weeks ago, we had that information, but we didn't keep it.
On a related issue:
Looking at a commit:
commit id-commit
parent id-1
parent id-2
parent id-3
Merge branch 'branch-2', 'branch-3'
One can tell the name of the branches for id-2 and id-3 (branch-2, 3),
but one can't tell the name of id-1.
At the time, those branches were not yet merged, this information was
available easily, even remotely via git-clone.
^ permalink raw reply
* Re: daily git packages for debian etch and sarge
From: Jakub Narebski @ 2006-05-13 12:31 UTC (permalink / raw)
To: git
In-Reply-To: <20060513122401.GC11845@cip.informatik.uni-erlangen.de>
Thomas Glanzmann wrote:
> is there someone who builds and publishes daily automatic git packages
> of Junios tree for debian sarge / etch (testing)?
http://git.or.cz/download.html
--
Jakub Narebski
Warsaw, Poland
^ permalink raw reply
* daily git packages for debian etch and sarge
From: Thomas Glanzmann @ 2006-05-13 12:24 UTC (permalink / raw)
To: GIT
Hello,
is there someone who builds and publishes daily automatic git packages
of Junios tree for debian sarge / etch (testing)?
Thomas
^ permalink raw reply
* Re: [RFC] qgit with tabs
From: Marco Costalba @ 2006-05-13 11:31 UTC (permalink / raw)
To: Pavel Roskin; +Cc: git
In-Reply-To: <20060513070726.qa5ssccws80go044@webmail.spamcop.net>
Hi Pavel,
>
> Just one thing for now. Double click on a file on the "rev list" tab should
> show the patch (what Ctrl-P would do), not the whole file. That would be more
> compatible with gitk, and it's what I normally need if I just browse the latest
> changes in the rev list.
>
Well, double click activates the current top entry in context menu.
This behaviour has not changed from past releases. To show the patch
perhaps you may, as always, double click on the selected revision, in
revisions list.
FWIK gitk does not have a file content viewer.
Thanks
Marco
^ permalink raw reply
* Re: [RFC] qgit with tabs
From: Pavel Roskin @ 2006-05-13 11:07 UTC (permalink / raw)
To: Marco Costalba; +Cc: git
In-Reply-To: <e5bfff550605130344n75e3e55eq533c49fc2a4f5483@mail.gmail.com>
Hello, Marco!
Quoting Marco Costalba <mcostalba@gmail.com>:
> I have pushed some patches that add tabs to qgit UI.
That's _really_ appreciated.
> I don't expect a new release any time soon, but I am interested to
> hear comments, especially on the usability front, so to be able to
> steer new development in advance.
Just one thing for now. Double click on a file on the "rev list" tab should
show the patch (what Ctrl-P would do), not the whole file. That would be more
compatible with gitk, and it's what I normally need if I just browse the latest
changes in the rev list.
> With new UI I found myself more and more using keyboard bindings
> instead of mouse:
>
> - r, p, f to switch to revisions list, patch and file views respectively
>
> - t to toggle tree view
>
> - s to toggle split view (very useful IMHO)
The later is very useful, but a bit hard to discover without checking the menu.
Maybe it should be a button in the toolbar.
> NOTE:
> Due to some repacking on a dumb host probably you need to re-clone:
I don't think re-clone should be needed. I didn't re-clone, yet I could update.
On the other hand, that host sometimes returns something that crashes
git-http-fetch. Sorry, no time to debug it right now. I guess it returns
error messages in HTML without reporting error 404, but git-http-fetch should
be more robust anyway.
--
Regards,
Pavel Roskin
^ permalink raw reply
* [RFC] qgit with tabs
From: Marco Costalba @ 2006-05-13 10:44 UTC (permalink / raw)
To: git
Hi all,
I have pushed some patches that add tabs to qgit UI.
I don't expect a new release any time soon, but I am interested to
hear comments, especially on the usability front, so to be able to
steer new development in advance.
With new UI I found myself more and more using keyboard bindings
instead of mouse:
- r, p, f to switch to revisions list, patch and file views respectively
- t to toggle tree view
- s to toggle split view (very useful IMHO)
NOTE:
Due to some repacking on a dumb host probably you need to re-clone:
git clone http://digilander.libero.it/mcostalba/scm/qgit.git
cd qgit
autoreconf -i
./configure
make
make install-strip
Marco
^ 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