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