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
9a8c2b6
Documentation
block-sha1
builtin
compat
contrib
ewah
git-gui
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
column.c
column.h
combine-diff.c
command-list.txt
commit-slab.h
commit.c
commit.h
config.c
config.mak.in
config.mak.uname
configure.ac
connect.c
connect.h
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.c
fetch-pack.h
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-merge-octopus.sh
git-merge-one-file.sh
git-merge-resolve.sh
git-mergetool--lib.sh
git-mergetool.sh
git-p4.py
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.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.rc
git.spec.in
gpg-interface.c
gpg-interface.h
graph.c
graph.h
grep.c
grep.h
hashmap.c
hashmap.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
khash.h
kwset.c
kwset.h
levenshtein.c
levenshtein.h
line-log.c
line-log.h
line-range.c
line-range.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-blobs.c
merge-blobs.h
merge-recursive.c
merge-recursive.h
merge.c
mergesort.c
mergesort.h
name-hash.c
notes-cache.c
notes-cache.h
notes-merge.c
notes-merge.h
notes-utils.c
notes-utils.h
notes.c
notes.h
object.c
object.h
pack-bitmap-write.c
pack-bitmap.c
pack-bitmap.h
pack-check.c
pack-objects.c
pack-objects.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
pathspec.c
pathspec.h
pkt-line.c
pkt-line.h
preload-index.c
pretty.c
prio-queue.c
prio-queue.h
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-testsvn.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.c
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-ctype.c
test-date.c
test-delta.c
test-dump-cache-tree.c
test-genrandom.c
test-hashmap.c
test-index-version.c
test-line-buffer.c
test-match-trees.c
test-mergesort.c
test-mktemp.c
test-parse-options.c
test-path-utils.c
test-prio-queue.c
test-read-cache.c
test-regex.c
test-revision-walking.c
test-run-command.c
test-scrap-cache-tree.c
test-sha1.c
test-sha1.sh
test-sigchain.c
test-string-list.c
test-subprocess.c
test-svn-fe.c
test-urlmatch-normalization.c
test-wildmatch.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
urlmatch.c
urlmatch.h
usage.c
userdiff.c
userdiff.h
utf8.c
utf8.h
varint.c
varint.h
version.c
version.h
versioncmp.c
walker.c
walker.h
wildmatch.c
wildmatch.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
/
reflog-walk.c
Blame
Blame
Latest commit
Brian Gesiak
and
Junio C Hamano
reflog-walk.c: rearrange xcalloc arguments
May 27, 2014
8e1aa2f
·
May 27, 2014
History
History
332 lines (295 loc) · 8.08 KB
Breadcrumbs
git
/
reflog-walk.c
Top
File metadata and controls
Code
Blame
332 lines (295 loc) · 8.08 KB
Raw
#include "cache.h" #include "commit.h" #include "refs.h" #include "diff.h" #include "revision.h" #include "string-list.h" #include "reflog-walk.h" struct complete_reflogs { char *ref; const char *short_ref; struct reflog_info { unsigned char osha1[20], nsha1[20]; char *email; unsigned long timestamp; int tz; char *message; } *items; int nr, alloc; }; static int read_one_reflog(unsigned char *osha1, unsigned char *nsha1, const char *email, unsigned long timestamp, int tz, const char *message, void *cb_data) { struct complete_reflogs *array = cb_data; struct reflog_info *item; ALLOC_GROW(array->items, array->nr + 1, array->alloc); item = array->items + array->nr; hashcpy(item->osha1, osha1); hashcpy(item->nsha1, nsha1); item->email = xstrdup(email); item->timestamp = timestamp; item->tz = tz; item->message = xstrdup(message); array->nr++; return 0; } static struct complete_reflogs *read_complete_reflog(const char *ref) { struct complete_reflogs *reflogs = xcalloc(1, sizeof(struct complete_reflogs)); reflogs->ref = xstrdup(ref); for_each_reflog_ent(ref, read_one_reflog, reflogs); if (reflogs->nr == 0) { unsigned char sha1[20]; const char *name; void *name_to_free; name = name_to_free = resolve_refdup(ref, sha1, 1, NULL); if (name) { for_each_reflog_ent(name, read_one_reflog, reflogs); free(name_to_free); } } if (reflogs->nr == 0) { int len = strlen(ref); char *refname = xmalloc(len + 12); sprintf(refname, "refs/%s", ref); for_each_reflog_ent(refname, read_one_reflog, reflogs); if (reflogs->nr == 0) { sprintf(refname, "refs/heads/%s", ref); for_each_reflog_ent(refname, read_one_reflog, reflogs); } free(refname); } return reflogs; } static int get_reflog_recno_by_time(struct complete_reflogs *array, unsigned long timestamp) { int i; for (i = array->nr - 1; i >= 0; i--) if (timestamp >= array->items[i].timestamp) return i; return -1; } struct commit_info_lifo { struct commit_info { struct commit *commit; void *util; } *items; int nr, alloc; }; static struct commit_info *get_commit_info(struct commit *commit, struct commit_info_lifo *lifo, int pop) { int i; for (i = 0; i < lifo->nr; i++) if (lifo->items[i].commit == commit) { struct commit_info *result = &lifo->items[i]; if (pop) { if (i + 1 < lifo->nr) memmove(lifo->items + i, lifo->items + i + 1, (lifo->nr - i) * sizeof(struct commit_info)); lifo->nr--; } return result; } return NULL; } static void add_commit_info(struct commit *commit, void *util, struct commit_info_lifo *lifo) { struct commit_info *info; ALLOC_GROW(lifo->items, lifo->nr + 1, lifo->alloc); info = lifo->items + lifo->nr; info->commit = commit; info->util = util; lifo->nr++; } struct commit_reflog { int recno; enum selector_type { SELECTOR_NONE, SELECTOR_INDEX, SELECTOR_DATE } selector; struct complete_reflogs *reflogs; }; struct reflog_walk_info { struct commit_info_lifo reflogs; struct string_list complete_reflogs; struct commit_reflog *last_commit_reflog; }; void init_reflog_walk(struct reflog_walk_info** info) { *info = xcalloc(1, sizeof(struct reflog_walk_info)); } int add_reflog_for_walk(struct reflog_walk_info *info, struct commit *commit, const char *name) { unsigned long timestamp = 0; int recno = -1; struct string_list_item *item; struct complete_reflogs *reflogs; char *branch, *at = strchr(name, '@'); struct commit_reflog *commit_reflog; enum selector_type selector = SELECTOR_NONE; if (commit->object.flags & UNINTERESTING) die ("Cannot walk reflogs for %s", name); branch = xstrdup(name); if (at && at[1] == '{') { char *ep; branch[at - name] = '\0'; recno = strtoul(at + 2, &ep, 10); if (*ep != '}') { recno = -1; timestamp = approxidate(at + 2); selector = SELECTOR_DATE; } else selector = SELECTOR_INDEX; } else recno = 0; item = string_list_lookup(&info->complete_reflogs, branch); if (item) reflogs = item->util; else { if (*branch == '\0') { unsigned char sha1[20]; free(branch); branch = resolve_refdup("HEAD", sha1, 0, NULL); if (!branch) die ("No current branch"); } reflogs = read_complete_reflog(branch); if (!reflogs || reflogs->nr == 0) { unsigned char sha1[20]; char *b; if (dwim_log(branch, strlen(branch), sha1, &b) == 1) { if (reflogs) { free(reflogs->ref); free(reflogs); } free(branch); branch = b; reflogs = read_complete_reflog(branch); } } if (!reflogs || reflogs->nr == 0) return -1; string_list_insert(&info->complete_reflogs, branch)->util = reflogs; } commit_reflog = xcalloc(1, sizeof(struct commit_reflog)); if (recno < 0) { commit_reflog->recno = get_reflog_recno_by_time(reflogs, timestamp); if (commit_reflog->recno < 0) { free(branch); free(commit_reflog); return -1; } } else commit_reflog->recno = reflogs->nr - recno - 1; commit_reflog->selector = selector; commit_reflog->reflogs = reflogs; add_commit_info(commit, commit_reflog, &info->reflogs); return 0; } void fake_reflog_parent(struct reflog_walk_info *info, struct commit *commit) { struct commit_info *commit_info = get_commit_info(commit, &info->reflogs, 0); struct commit_reflog *commit_reflog; struct reflog_info *reflog; info->last_commit_reflog = NULL; if (!commit_info) return; commit_reflog = commit_info->util; if (commit_reflog->recno < 0) { commit->parents = NULL; return; } reflog = &commit_reflog->reflogs->items[commit_reflog->recno]; info->last_commit_reflog = commit_reflog; commit_reflog->recno--; commit_info->commit = (struct commit *)parse_object(reflog->osha1); if (!commit_info->commit) { commit->parents = NULL; return; } commit->parents = xcalloc(1, sizeof(struct commit_list)); commit->parents->item = commit_info->commit; } void get_reflog_selector(struct strbuf *sb, struct reflog_walk_info *reflog_info, enum date_mode dmode, int force_date, int shorten) { struct commit_reflog *commit_reflog = reflog_info->last_commit_reflog; struct reflog_info *info; const char *printed_ref; if (!commit_reflog) return; if (shorten) { if (!commit_reflog->reflogs->short_ref) commit_reflog->reflogs->short_ref = shorten_unambiguous_ref(commit_reflog->reflogs->ref, 0); printed_ref = commit_reflog->reflogs->short_ref; } else { printed_ref = commit_reflog->reflogs->ref; } strbuf_addf(sb, "%s@{", printed_ref); if (commit_reflog->selector == SELECTOR_DATE || (commit_reflog->selector == SELECTOR_NONE && force_date)) { info = &commit_reflog->reflogs->items[commit_reflog->recno+1]; strbuf_addstr(sb, show_date(info->timestamp, info->tz, dmode)); } else { strbuf_addf(sb, "%d", commit_reflog->reflogs->nr - 2 - commit_reflog->recno); } strbuf_addch(sb, '}'); } void get_reflog_message(struct strbuf *sb, struct reflog_walk_info *reflog_info) { struct commit_reflog *commit_reflog = reflog_info->last_commit_reflog; struct reflog_info *info; size_t len; if (!commit_reflog) return; info = &commit_reflog->reflogs->items[commit_reflog->recno+1]; len = strlen(info->message); if (len > 0) len--; /* strip away trailing newline */ strbuf_add(sb, info->message, len); } const char *get_reflog_ident(struct reflog_walk_info *reflog_info) { struct commit_reflog *commit_reflog = reflog_info->last_commit_reflog; struct reflog_info *info; if (!commit_reflog) return NULL; info = &commit_reflog->reflogs->items[commit_reflog->recno+1]; return info->email; } void show_reflog_message(struct reflog_walk_info *reflog_info, int oneline, enum date_mode dmode, int force_date) { if (reflog_info && reflog_info->last_commit_reflog) { struct commit_reflog *commit_reflog = reflog_info->last_commit_reflog; struct reflog_info *info; struct strbuf selector = STRBUF_INIT; info = &commit_reflog->reflogs->items[commit_reflog->recno+1]; get_reflog_selector(&selector, reflog_info, dmode, force_date, 0); if (oneline) { printf("%s: %s", selector.buf, info->message); } else { printf("Reflog: %s (%s)\nReflog message: %s", selector.buf, info->email, info->message); } strbuf_release(&selector); } }
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
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
You can’t perform that action at this time.