Skip to content
Navigation Menu
Toggle navigation
Sign in
In this repository
All GitHub Enterprise
↵
Jump to
↵
No suggested jump to results
In this repository
All GitHub Enterprise
↵
Jump to
↵
In this organization
All GitHub Enterprise
↵
Jump to
↵
In this repository
All GitHub Enterprise
↵
Jump to
↵
Sign in
Reseting focus
You signed in with another tab or window.
Reload
to refresh your session.
You signed out in another tab or window.
Reload
to refresh your session.
You switched accounts on another tab or window.
Reload
to refresh your session.
Dismiss alert
{{ message }}
git-mirror
/
git
Public
Notifications
You must be signed in to change notification settings
Fork
0
Star
0
Code
Issues
0
Pull requests
0
Actions
Projects
0
Security
Insights
Additional navigation options
Code
Issues
Pull requests
Actions
Projects
Security
Insights
Files
d9955fd
Documentation
block-sha1
builtin
compat
contrib
git-gui
git_remote_helpers
gitk-git
gitweb
mergetools
perl
po
ppc
t
templates
vcs-svn
xdiff
.gitattributes
.gitignore
.mailmap
COPYING
GIT-VERSION-GEN
INSTALL
LGPL-2.1
Makefile
README
RelNotes
abspath.c
aclocal.m4
advice.c
advice.h
alias.c
alloc.c
archive-tar.c
archive-zip.c
archive.c
archive.h
argv-array.c
argv-array.h
attr.c
attr.h
base85.c
bisect.c
bisect.h
blob.c
blob.h
branch.c
branch.h
builtin.h
bulk-checkin.c
bulk-checkin.h
bundle.c
bundle.h
cache-tree.c
cache-tree.h
cache.h
check-builtins.sh
check-racy.c
check_bindir
color.c
color.h
combine-diff.c
command-list.txt
commit.c
commit.h
config.c
config.mak.in
configure.ac
connect.c
connected.c
connected.h
convert.c
convert.h
copy.c
credential-cache--daemon.c
credential-cache.c
credential-store.c
credential.c
credential.h
csum-file.c
csum-file.h
ctype.c
daemon.c
date.c
decorate.c
decorate.h
delta.h
diff-delta.c
diff-lib.c
diff-no-index.c
diff.c
diff.h
diffcore-break.c
diffcore-delta.c
diffcore-order.c
diffcore-pickaxe.c
diffcore-rename.c
diffcore.h
dir.c
dir.h
editor.c
entry.c
environment.c
exec_cmd.c
exec_cmd.h
fast-import.c
fetch-pack.h
fixup-builtins
fmt-merge-msg.h
fsck.c
fsck.h
generate-cmdlist.sh
gettext.c
gettext.h
git-add--interactive.perl
git-am.sh
git-archimport.perl
git-bisect.sh
git-compat-util.h
git-cvsexportcommit.perl
git-cvsimport.perl
git-cvsserver.perl
git-difftool--helper.sh
git-difftool.perl
git-filter-branch.sh
git-instaweb.sh
git-lost-found.sh
git-merge-octopus.sh
git-merge-one-file.sh
git-merge-resolve.sh
git-mergetool--lib.sh
git-mergetool.sh
git-parse-remote.sh
git-pull.sh
git-quiltimport.sh
git-rebase--am.sh
git-rebase--interactive.sh
git-rebase--merge.sh
git-rebase.sh
git-relink.perl
git-remote-testgit.py
git-repack.sh
git-request-pull.sh
git-send-email.perl
git-sh-i18n.sh
git-sh-setup.sh
git-stash.sh
git-submodule.sh
git-svn.perl
git-web--browse.sh
git.c
git.spec.in
gpg-interface.c
gpg-interface.h
graph.c
graph.h
grep.c
grep.h
hash.c
hash.h
help.c
help.h
hex.c
http-backend.c
http-fetch.c
http-push.c
http-walker.c
http.c
http.h
ident.c
imap-send.c
kwset.c
kwset.h
levenshtein.c
levenshtein.h
list-objects.c
list-objects.h
ll-merge.c
ll-merge.h
lockfile.c
log-tree.c
log-tree.h
mailmap.c
mailmap.h
match-trees.c
merge-file.c
merge-file.h
merge-recursive.c
merge-recursive.h
name-hash.c
notes-cache.c
notes-cache.h
notes-merge.c
notes-merge.h
notes.c
notes.h
object.c
object.h
pack-check.c
pack-refs.c
pack-refs.h
pack-revindex.c
pack-revindex.h
pack-write.c
pack.h
pager.c
parse-options-cb.c
parse-options.c
parse-options.h
patch-delta.c
patch-ids.c
patch-ids.h
path.c
pkt-line.c
pkt-line.h
preload-index.c
pretty.c
progress.c
progress.h
prompt.c
prompt.h
quote.c
quote.h
reachable.c
reachable.h
read-cache.c
reflog-walk.c
reflog-walk.h
refs.c
refs.h
remote-curl.c
remote.c
remote.h
replace_object.c
rerere.c
rerere.h
resolve-undo.c
resolve-undo.h
revision.c
revision.h
run-command.c
run-command.h
send-pack.h
sequencer.c
sequencer.h
server-info.c
setup.c
sh-i18n--envsubst.c
sha1-array.c
sha1-array.h
sha1-lookup.c
sha1-lookup.h
sha1_file.c
sha1_name.c
shallow.c
shell.c
shortlog.h
show-index.c
sideband.c
sideband.h
sigchain.c
sigchain.h
strbuf.c
strbuf.h
streaming.c
streaming.h
string-list.c
string-list.h
submodule.c
submodule.h
symlinks.c
tag.c
tag.h
tar.h
test-chmtime.c
test-credential.c
test-ctype.c
test-date.c
test-delta.c
test-dump-cache-tree.c
test-genrandom.c
test-index-version.c
test-line-buffer.c
test-match-trees.c
test-mktemp.c
test-obj-pool.c
test-parse-options.c
test-path-utils.c
test-run-command.c
test-scrap-cache-tree.c
test-sha1.c
test-sha1.sh
test-sigchain.c
test-string-pool.c
test-subprocess.c
test-svn-fe.c
test-treap.c
thread-utils.c
thread-utils.h
trace.c
transport-helper.c
transport.c
transport.h
tree-diff.c
tree-walk.c
tree-walk.h
tree.c
tree.h
unimplemented.sh
unix-socket.c
unix-socket.h
unpack-trees.c
unpack-trees.h
upload-pack.c
url.c
url.h
usage.c
userdiff.c
userdiff.h
utf8.c
utf8.h
walker.c
walker.h
wrap-for-bin.sh
wrapper.c
write_or_die.c
ws.c
wt-status.c
wt-status.h
xdiff-interface.c
xdiff-interface.h
zlib.c
Breadcrumbs
git
/
ident.c
Blame
Blame
Latest commit
History
History
387 lines (344 loc) · 8.6 KB
Breadcrumbs
git
/
ident.c
Top
File metadata and controls
Code
Blame
387 lines (344 loc) · 8.6 KB
Raw
/* * ident.c * * create git identifier lines of the form "name <email> date" * * Copyright (C) 2005 Linus Torvalds */ #include "cache.h" static char git_default_date[50]; #ifdef NO_GECOS_IN_PWENT #define get_gecos(ignored) "&" #else #define get_gecos(struct_passwd) ((struct_passwd)->pw_gecos) #endif static void copy_gecos(const struct passwd *w, char *name, size_t sz) { char *src, *dst; size_t len, nlen; nlen = strlen(w->pw_name); /* Traditionally GECOS field had office phone numbers etc, separated * with commas. Also & stands for capitalized form of the login name. */ for (len = 0, dst = name, src = get_gecos(w); len < sz; src++) { int ch = *src; if (ch != '&') { *dst++ = ch; if (ch == 0 || ch == ',') break; len++; continue; } if (len + nlen < sz) { /* Sorry, Mr. McDonald... */ *dst++ = toupper(*w->pw_name); memcpy(dst, w->pw_name + 1, nlen - 1); dst += nlen - 1; len += nlen; } } if (len < sz) name[len] = 0; else die("Your parents must have hated you!"); } static int add_mailname_host(char *buf, size_t len) { FILE *mailname; mailname = fopen("/etc/mailname", "r"); if (!mailname) { if (errno != ENOENT) warning("cannot open /etc/mailname: %s", strerror(errno)); return -1; } if (!fgets(buf, len, mailname)) { if (ferror(mailname)) warning("cannot read /etc/mailname: %s", strerror(errno)); fclose(mailname); return -1; } /* success! */ fclose(mailname); return 0; } static void add_domainname(char *buf, size_t len) { struct hostent *he; size_t namelen; const char *domainname; if (gethostname(buf, len)) { warning("cannot get host name: %s", strerror(errno)); strlcpy(buf, "(none)", len); return; } namelen = strlen(buf); if (memchr(buf, '.', namelen)) return; he = gethostbyname(buf); buf[namelen++] = '.'; buf += namelen; len -= namelen; if (he && (domainname = strchr(he->h_name, '.'))) strlcpy(buf, domainname + 1, len); else strlcpy(buf, "(none)", len); } static void copy_email(const struct passwd *pw) { /* * Make up a fake email address * (name + '@' + hostname [+ '.' + domainname]) */ size_t len = strlen(pw->pw_name); if (len > sizeof(git_default_email)/2) die("Your sysadmin must hate you!"); memcpy(git_default_email, pw->pw_name, len); git_default_email[len++] = '@'; if (!add_mailname_host(git_default_email + len, sizeof(git_default_email) - len)) return; /* read from "/etc/mailname" (Debian) */ add_domainname(git_default_email + len, sizeof(git_default_email) - len); } static void setup_ident(const char **name, const char **emailp) { struct passwd *pw = NULL; /* Get the name ("gecos") */ if (!*name && !git_default_name[0]) { pw = getpwuid(getuid()); if (!pw) die("You don't exist. Go away!"); copy_gecos(pw, git_default_name, sizeof(git_default_name)); } if (!*name) *name = git_default_name; if (!*emailp && !git_default_email[0]) { const char *email = getenv("EMAIL"); if (email && email[0]) { strlcpy(git_default_email, email, sizeof(git_default_email)); user_ident_explicitly_given |= IDENT_MAIL_GIVEN; } else { if (!pw) pw = getpwuid(getuid()); if (!pw) die("You don't exist. Go away!"); copy_email(pw); } } if (!*emailp) *emailp = git_default_email; /* And set the default date */ if (!git_default_date[0]) datestamp(git_default_date, sizeof(git_default_date)); } static int add_raw(char *buf, size_t size, int offset, const char *str) { size_t len = strlen(str); if (offset + len > size) return size; memcpy(buf + offset, str, len); return offset + len; } static int crud(unsigned char c) { return c <= 32 || c == '.' || c == ',' || c == ':' || c == ';' || c == '<' || c == '>' || c == '"' || c == '\\' || c == '\''; } /* * Copy over a string to the destination, but avoid special * characters ('\n', '<' and '>') and remove crud at the end */ static int copy(char *buf, size_t size, int offset, const char *src) { size_t i, len; unsigned char c; /* Remove crud from the beginning.. */ while ((c = *src) != 0) { if (!crud(c)) break; src++; } /* Remove crud from the end.. */ len = strlen(src); while (len > 0) { c = src[len-1]; if (!crud(c)) break; --len; } /* * Copy the rest to the buffer, but avoid the special * characters '\n' '<' and '>' that act as delimiters on * an identification line */ for (i = 0; i < len; i++) { c = *src++; switch (c) { case '\n': case '<': case '>': continue; } if (offset >= size) return size; buf[offset++] = c; } return offset; } /* * Reverse of fmt_ident(); given an ident line, split the fields * to allow the caller to parse it. * Signal a success by returning 0, but date/tz fields of the result * can still be NULL if the input line only has the name/email part * (e.g. reading from a reflog entry). */ int split_ident_line(struct ident_split *split, const char *line, int len) { const char *cp; size_t span; int status = -1; memset(split, 0, sizeof(*split)); split->name_begin = line; for (cp = line; *cp && cp < line + len; cp++) if (*cp == '<') { split->mail_begin = cp + 1; break; } if (!split->mail_begin) return status; for (cp = split->mail_begin - 2; line <= cp; cp--) if (!isspace(*cp)) { split->name_end = cp + 1; break; } if (!split->name_end) return status; for (cp = split->mail_begin; cp < line + len; cp++) if (*cp == '>') { split->mail_end = cp; break; } if (!split->mail_end) return status; for (cp = split->mail_end + 1; cp < line + len && isspace(*cp); cp++) ; if (line + len <= cp) goto person_only; split->date_begin = cp; span = strspn(cp, "0123456789"); if (!span) goto person_only; split->date_end = split->date_begin + span; for (cp = split->date_end; cp < line + len && isspace(*cp); cp++) ; if (line + len <= cp || (*cp != '+' && *cp != '-')) goto person_only; split->tz_begin = cp; span = strspn(cp + 1, "0123456789"); if (!span) goto person_only; split->tz_end = split->tz_begin + 1 + span; return 0; person_only: split->date_begin = NULL; split->date_end = NULL; split->tz_begin = NULL; split->tz_end = NULL; return 0; } static const char *env_hint = "\n" "*** Please tell me who you are.\n" "\n" "Run\n" "\n" " git config --global user.email \"you@example.com\"\n" " git config --global user.name \"Your Name\"\n" "\n" "to set your account\'s default identity.\n" "Omit --global to set the identity only in this repository.\n" "\n"; const char *fmt_ident(const char *name, const char *email, const char *date_str, int flag) { static char buffer[1000]; char date[50]; int i; int error_on_no_name = (flag & IDENT_ERROR_ON_NO_NAME); int warn_on_no_name = (flag & IDENT_WARN_ON_NO_NAME); int name_addr_only = (flag & IDENT_NO_DATE); setup_ident(&name, &email); if (!*name) { struct passwd *pw; if ((warn_on_no_name || error_on_no_name) && name == git_default_name && env_hint) { fputs(env_hint, stderr); env_hint = NULL; /* warn only once */ } if (error_on_no_name) die("empty ident %s <%s> not allowed", name, email); pw = getpwuid(getuid()); if (!pw) die("You don't exist. Go away!"); strlcpy(git_default_name, pw->pw_name, sizeof(git_default_name)); name = git_default_name; } strcpy(date, git_default_date); if (!name_addr_only && date_str && date_str[0]) { if (parse_date(date_str, date, sizeof(date)) < 0) die("invalid date format: %s", date_str); } i = copy(buffer, sizeof(buffer), 0, name); i = add_raw(buffer, sizeof(buffer), i, " <"); i = copy(buffer, sizeof(buffer), i, email); if (!name_addr_only) { i = add_raw(buffer, sizeof(buffer), i, "> "); i = copy(buffer, sizeof(buffer), i, date); } else { i = add_raw(buffer, sizeof(buffer), i, ">"); } if (i >= sizeof(buffer)) die("Impossibly long personal identifier"); buffer[i] = 0; return buffer; } const char *fmt_name(const char *name, const char *email) { return fmt_ident(name, email, NULL, IDENT_ERROR_ON_NO_NAME | IDENT_NO_DATE); } const char *git_author_info(int flag) { return fmt_ident(getenv("GIT_AUTHOR_NAME"), getenv("GIT_AUTHOR_EMAIL"), getenv("GIT_AUTHOR_DATE"), flag); } const char *git_committer_info(int flag) { if (getenv("GIT_COMMITTER_NAME")) user_ident_explicitly_given |= IDENT_NAME_GIVEN; if (getenv("GIT_COMMITTER_EMAIL")) user_ident_explicitly_given |= IDENT_MAIL_GIVEN; return fmt_ident(getenv("GIT_COMMITTER_NAME"), getenv("GIT_COMMITTER_EMAIL"), getenv("GIT_COMMITTER_DATE"), flag); } int user_ident_sufficiently_given(void) { #ifndef WINDOWS return (user_ident_explicitly_given & IDENT_MAIL_GIVEN); #else return (user_ident_explicitly_given == IDENT_ALL_GIVEN); #endif }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
You can’t perform that action at this time.