1 #+TITLE: org-git-link.el -- link to specific git revisions
2 #+OPTIONS: ^:{} author:nil toc:nil
4 # This file is released by its authors and contributors under the GNU
5 # Free Documentation license v1.3 or later, code examples are released
6 # under the GNU General Public License v3 or later.
8 org-git-link allows linking to specific (git) versions of a file.
12 Often one wants to link to a specific version of a reference
13 document which may change in time. Thorsten Wagner described an
14 important use case in his mailing list entry
15 ([[https://orgmode.org/list/200907241232.52729.torsten.wagner@googlemail.com]]), namely
16 linking to results in a lab book. Quote:
19 [...] Please think about the following situation: I have
20 something like "... In the [graph] of the last results, a huge
21 peak is observable due to measurement problems for the
22 following set-up parameters ...." in my org-file and then
23 several month later in a stupid act I overwrite this file by
24 some very similar but different results, e.g. because I was not
25 longer aware of the link and thought there is no need to keep
26 this old graph with the ugly peak and replace it by something
27 "better". Now the link still depicts to a graph (lets say
28 without or smaller peak) and back in org-mode I might reread my
29 entries check what I did several months ago... and I will be
30 very confused since the graph and the written text have some
31 quirks (refer to a peak where no peak is depict in the graph
32 and refers to wrong measurement parameters) my boss ask me what
33 sort of mess I did, which I can not explain. He claims its the
34 fault of all this "linux-hacker-
35 emacs-org-mode-work-only-on-text-files"-stuff blaims me to dead
36 and force me switching back to use Outlook, MS Office and MS
37 Windows for the rest of my life..... wooohhh that would be a
41 What a sad story indeed. Collaborative editing is another case
42 where linking of (e.g.) todo items to specific versions or to
43 files in different branches comes in handy.
45 * Specifying revisions
47 =org-git-link.el= defines two new link types. The =git= link
48 type is meant to be used in the typical scenario and mimics the
49 =file= link syntax as closely as possible. The =gitbare= link
50 type exists mostly for debugging reasons, but also allows e.g.
51 linking to files in a bare git repository for the experts. I
52 will first show an example usage for both kinds of links before
53 the syntax is defined more formally.
57 In the lab book use case described above assume that the org
58 file in located in =/home/user/repo/planning/labbook.org= and
59 the measurement data is visualized in
60 =/home/user/repo/data/result.png=. The data is so exciting that
61 the relevant commit has been tagged =nobelprize=. Then the
62 links in a lab book entry could read any of the following:
64 - [[git:../data/result.png::master@{3.10.2009}]]
65 - [[git:/home/user/repo/data/results.png::nobelprize]]
66 - [[gitbare:../.git::nobelprize:data/results.png]]
69 For usage in collaborative editing, typical entries might be:
71 * TODO Merge [[git:paper.tex::theirstuff][Their version]] with [[git:paper.tex::ourstuff][Our version]]
72 * [[git:answer.txt::firstround][Answer]] to [[git:report.txt::firstround][Referee report]] of our paper
73 * [[gitbare:/path/to/centralrepos.git::simulation.cpp][Simulation program]]
76 In all these examples, the linked files do not even have to exist
77 in the working repository, i.e. the links continue to work even
78 after the files have been deleted.
80 ** Formal specification
84 [[git:/path/to/file::searchstring]]
86 This form is the familiar from normal org file links
87 including search options [[info:org#Search options][Search options]]. However, its use is
88 restricted to files in a working directory and does not
89 handle bare repositories on purpose (see the bare form for
92 The search string references a commit (a tree-ish in Git
93 terminology). The two most useful types of search strings are
95 - A symbolic ref name, usually a branch or tag name (e.g.
96 master or nobelprize).
97 - A ref followed by the suffix @ with a date specification
98 enclosed in a brace pair (e.g. {yesterday}, {1 month 2
99 weeks 3 days 1 hour 1 second ago} or {1979-02-26 18:30:00})
100 to specify the value of the ref at a prior point in time
102 For other ways to specify commits see the git documentation
103 referenced in the [[*Bare git form][bare git section]].
106 From the (not necessarily existing) file path first the
107 corresponding git directory is extracted. This is done in the
108 following way: Starting with the directory of the linken
109 file, it is checked whether
111 - the directory exists and
112 - whether a .git subdirectory exists.
114 If not, the procedure is iterated with the parent directory.
115 The link path (which can be given as a local link) is thus
116 separated into an absolute path GIT_DIR to the git directory
117 (without .git) and a relative path RELPATH to the file. Git
119 : git --no-pager --git-dir=GIT_DIR/.git show SEARCHSTRING:RELPATH
124 [[gitbare:GIT_DIR::OBJECT]]
126 This is the more bare metal version, which gives the user most
127 control. It directly translates to the git command
128 : git --no-pager --git-dir=GIT_DIR show OBJECT
129 Using this version one can also view files from a bare git
130 repository. For detailed information on how to specify an
131 object, see the man page of =git-rev-parse= (section
132 SPECIFYING REVISIONS). A specific blob (file) can be
133 specified by a suffix clolon (:) followed by a path.
135 ** Following a git link
137 Following any of the git links creates a direcory named
138 =org-git-link-SHA= under =temporary-file-directory= (if it
139 does not exist), where SHA is the hash of the linked file
140 (blob). The file contents is saved within this directory under
141 the name used in the link. This ensures that each file is only
142 checked out once, even when they are referenced by different
143 search strings (e.g. once by branch name and once by tag). The
144 file is supsequently opened using =org-open-file=, which does
145 the right thing for non-text files as well.
147 ** Creating a git link
149 As an org mode is a simple text file, a git link can of course
150 be inserted directly as a string. For your convenience two functions creating links
151 automatically have been defined:
153 - org-git-store-link :: This function is automatically added
154 to =org-store-link-functions=. When =org-store-link=
155 (usually bound to =C-c l=) is called in a buffer whose
156 file is in a git repository, it creates a git link to the
157 file version corresponding to the current branchname and
158 date. The link is then added to =org-stored-links=, from
159 where it can be inserted with =org-insert-link(-global)=,
160 usually bound to =C-c C-l=.
162 - org-git-insert-link-interactively :: This function
163 interactively asks for a file name, a search string, and
164 a description. The corresponding link is then inserted at
165 point. Currently the only advantage over writing the link
166 directly is file completion. Completion of the search
167 string with the help of current tags and branch names
168 might be implemented at a later stage, if demand exists.