Skip to content

Commit 6aa33f4

Browse files
author
Linus Torvalds
committed
Abstract out the "name <email> date" handling of commit-tree.c
We'll want to use it for the tagging too.
1 parent 26a2d8a commit 6aa33f4

File tree

4 files changed

+156
-71
lines changed

4 files changed

+156
-71
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ install: $(PROG) $(SCRIPTS)
5858

5959
LIB_OBJS=read-cache.o sha1_file.o usage.o object.o commit.o tree.o blob.o \
6060
tag.o date.o index.o diff-delta.o patch-delta.o entry.o path.o \
61-
epoch.o refs.o csum-file.o pack-check.o pkt-line.o connect.o
61+
epoch.o refs.o csum-file.o pack-check.o pkt-line.o connect.o ident.o
6262
LIB_FILE=libgit.a
6363
LIB_H=cache.h object.h blob.h tree.h commit.h tag.h delta.h epoch.h csum-file.h \
6464
pack.h pkt-line.h refs.h

cache.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,9 @@ const char *show_date(unsigned long time, int timezone);
211211
void parse_date(const char *date, char *buf, int bufsize);
212212
void datestamp(char *buf, int bufsize);
213213

214+
extern int setup_ident(void);
215+
extern char *get_ident(const char *name, const char *email, const char *date_str);
216+
214217
static inline void *xmalloc(size_t size)
215218
{
216219
void *ret = malloc(size);

commit-tree.c

Lines changed: 14 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -45,39 +45,6 @@ static void add_buffer(char **bufp, unsigned int *sizep, const char *fmt, ...)
4545
memcpy(buf + size, one_line, len);
4646
}
4747

48-
static void remove_special(char *p)
49-
{
50-
char c;
51-
char *dst = p, *src = p;
52-
53-
for (;;) {
54-
c = *src;
55-
src++;
56-
switch(c) {
57-
case '\n': case '<': case '>':
58-
continue;
59-
}
60-
*dst++ = c;
61-
if (!c)
62-
break;
63-
}
64-
65-
/*
66-
* Go back, and remove crud from the end: some people
67-
* have commas etc in their gecos field
68-
*/
69-
dst--;
70-
while (--dst >= p) {
71-
unsigned char c = *dst;
72-
switch (c) {
73-
case ',': case ';': case '.':
74-
*dst = 0;
75-
continue;
76-
}
77-
break;
78-
}
79-
}
80-
8148
static void check_valid(unsigned char *sha1, const char *expect)
8249
{
8350
void *buf;
@@ -112,18 +79,23 @@ static int new_parent(int idx)
11279
return 1;
11380
}
11481

82+
static char *git_author_info(void)
83+
{
84+
return get_ident(gitenv("GIT_AUTHOR_NAME"), gitenv("GIT_AUTHOR_EMAIL"), gitenv("GIT_AUTHOR_DATE"));
85+
}
86+
87+
static char *git_committer_info(void)
88+
{
89+
return get_ident(gitenv("GIT_COMMITTER_NAME"), gitenv("GIT_COMMITTER_EMAIL"), gitenv("GIT_COMMITTER_DATE"));
90+
}
91+
11592
int main(int argc, char **argv)
11693
{
117-
int i, len;
94+
int i;
11895
int parents = 0;
11996
unsigned char tree_sha1[20];
12097
unsigned char commit_sha1[20];
121-
char *gecos, *realgecos, *commitgecos;
122-
char *email, *commitemail, realemail[1000];
123-
char date[50], realdate[50];
124-
char *audate, *cmdate;
12598
char comment[1000];
126-
struct passwd *pw;
12799
char *buffer;
128100
unsigned int size;
129101

@@ -142,35 +114,7 @@ int main(int argc, char **argv)
142114
}
143115
if (!parents)
144116
fprintf(stderr, "Committing initial tree %s\n", argv[1]);
145-
pw = getpwuid(getuid());
146-
if (!pw)
147-
die("You don't exist. Go away!");
148-
realgecos = pw->pw_gecos;
149-
len = strlen(pw->pw_name);
150-
memcpy(realemail, pw->pw_name, len);
151-
realemail[len] = '@';
152-
gethostname(realemail+len+1, sizeof(realemail)-len-1);
153-
if (!strchr(realemail+len+1, '.')) {
154-
strcat(realemail, ".");
155-
getdomainname(realemail+strlen(realemail), sizeof(realemail)-strlen(realemail)-1);
156-
}
157-
158-
datestamp(realdate, sizeof(realdate));
159-
strcpy(date, realdate);
160-
161-
commitgecos = gitenv("GIT_COMMITTER_NAME") ? : realgecos;
162-
commitemail = gitenv("GIT_COMMITTER_EMAIL") ? : realemail;
163-
gecos = gitenv("GIT_AUTHOR_NAME") ? : realgecos;
164-
email = gitenv("GIT_AUTHOR_EMAIL") ? : realemail;
165-
audate = gitenv("GIT_AUTHOR_DATE");
166-
if (audate)
167-
parse_date(audate, date, sizeof(date));
168-
cmdate = gitenv("GIT_COMMITTER_DATE");
169-
if (cmdate)
170-
parse_date(cmdate, realdate, sizeof(realdate));
171-
172-
remove_special(gecos); remove_special(realgecos); remove_special(commitgecos);
173-
remove_special(email); remove_special(realemail); remove_special(commitemail);
117+
setup_ident();
174118

175119
init_buffer(&buffer, &size);
176120
add_buffer(&buffer, &size, "tree %s\n", sha1_to_hex(tree_sha1));
@@ -184,8 +128,8 @@ int main(int argc, char **argv)
184128
add_buffer(&buffer, &size, "parent %s\n", sha1_to_hex(parent_sha1[i]));
185129

186130
/* Person/date information */
187-
add_buffer(&buffer, &size, "author %s <%s> %s\n", gecos, email, date);
188-
add_buffer(&buffer, &size, "committer %s <%s> %s\n\n", commitgecos, commitemail, realdate);
131+
add_buffer(&buffer, &size, "author %s\n", git_author_info());
132+
add_buffer(&buffer, &size, "committer %s\n\n", git_committer_info());
189133

190134
/* And add the comment */
191135
while (fgets(comment, sizeof(comment), stdin) != NULL)

ident.c

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
/*
2+
* ident.c
3+
*
4+
* create git identifier lines of the form "name <email> date"
5+
*
6+
* Copyright (C) 2005 Linus Torvalds
7+
*/
8+
#include "cache.h"
9+
10+
#include <pwd.h>
11+
#include <time.h>
12+
#include <ctype.h>
13+
14+
static char real_email[1000];
15+
static char real_name[1000];
16+
static char real_date[50];
17+
18+
int setup_ident(void)
19+
{
20+
int len;
21+
struct passwd *pw = getpwuid(getuid());
22+
23+
if (!pw)
24+
die("You don't exist. Go away!");
25+
26+
/* Get the name ("gecos") */
27+
len = strlen(pw->pw_gecos);
28+
if (len >= sizeof(real_name))
29+
die("Your parents must have hated you");
30+
memcpy(real_name, pw->pw_gecos, len+1);
31+
32+
/* Make up a fake email address (name + '@' + hostname [+ '.' + domainname]) */
33+
len = strlen(pw->pw_name);
34+
if (len > sizeof(real_email)/2)
35+
die("Your parents must have hated you");
36+
memcpy(real_email, pw->pw_name, len);
37+
real_email[len++] = '@';
38+
gethostname(real_email + len, sizeof(real_email) - len);
39+
if (!strchr(real_email+len, '.')) {
40+
len = strlen(real_email);
41+
real_email[len++] = '.';
42+
getdomainname(real_email+len, sizeof(real_email)-len);
43+
}
44+
45+
/* And set the default date */
46+
datestamp(real_date, sizeof(real_date));
47+
return 0;
48+
}
49+
50+
static int add_raw(char *buf, int size, int offset, const char *str)
51+
{
52+
int len = strlen(str);
53+
if (offset + len > size)
54+
return size;
55+
memcpy(buf + offset, str, len);
56+
return offset + len;
57+
}
58+
59+
static int crud(unsigned char c)
60+
{
61+
static const char crud_array[256] = {
62+
[0 ... 31] = 1,
63+
[' '] = 1,
64+
['.'] = 1, [','] = 1,
65+
[':'] = 1, [';'] = 1,
66+
['<'] = 1, ['>'] = 1,
67+
['"'] = 1, ['\''] = 1,
68+
};
69+
return crud_array[c];
70+
}
71+
72+
/*
73+
* Copy over a string to the destination, but avoid special
74+
* characters ('\n', '<' and '>') and remove crud at the end
75+
*/
76+
static int copy(char *buf, int size, int offset, const char *src)
77+
{
78+
int i, len;
79+
unsigned char c;
80+
81+
/* Remove crud from the beginning.. */
82+
while ((c = *src) != 0) {
83+
if (!crud(c))
84+
break;
85+
src++;
86+
}
87+
88+
/* Remove crud from the end.. */
89+
len = strlen(src);
90+
while (len > 0) {
91+
c = src[len-1];
92+
if (!crud(c))
93+
break;
94+
--len;
95+
}
96+
97+
/*
98+
* Copy the rest to the buffer, but avoid the special
99+
* characters '\n' '<' and '>' that act as delimeters on
100+
* a identification line
101+
*/
102+
for (i = 0; i < len; i++) {
103+
c = *src++;
104+
switch (c) {
105+
case '\n': case '<': case '>':
106+
continue;
107+
}
108+
if (offset >= size)
109+
return size;
110+
buf[offset++] = c;
111+
}
112+
return offset;
113+
}
114+
115+
char *get_ident(const char *name, const char *email, const char *date_str)
116+
{
117+
static char buffer[1000];
118+
char date[50];
119+
int i;
120+
121+
if (!name)
122+
name = real_name;
123+
if (!email)
124+
email = real_email;
125+
strcpy(date, real_date);
126+
if (date_str)
127+
parse_date(date_str, date, sizeof(date));
128+
129+
i = copy(buffer, sizeof(buffer), 0, name);
130+
i = add_raw(buffer, sizeof(buffer), i, " <");
131+
i = copy(buffer, sizeof(buffer), i, email);
132+
i = add_raw(buffer, sizeof(buffer), i, "> ");
133+
i = copy(buffer, sizeof(buffer), i, date);
134+
if (i >= sizeof(buffer))
135+
die("Impossibly long personal identifier");
136+
buffer[i] = 0;
137+
return buffer;
138+
}

0 commit comments

Comments
 (0)