744f1983150936d8c634426070d57801c534a03c
[webgit] / src / worktree.c
1 /*
2     cehtehs git web frontend
3
4   Copyright (C)
5     2008,               Christian Thaeter <ct@pipapo.org>
6
7   This program is free software: you can redistribute it and/or modify
8   it under the terms of the GNU Affero General Public License as published by
9   the Free Software Foundation, either version 3 of the License, or
10   (at your option) any later version.
11
12   This program is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU Affero General Public License for more details.
16
17   You should have received a copy of the GNU Affero General Public License
18   along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "worktree.h"
22 #include "object.h"
23
24 #define SHA1_HEADER <openssl/sha.h>
25 #include "git/cache.h"
26 #include "git/commit.h"
27 #include "git/refs.h"
28 #include "git/tree.h"
29
30 static int
31 webgit_worktree_create (struct webgit_repo_info* repo,
32                         const char* ref,
33                         unsigned char* sha1_tree,
34                         unsigned char* sha1_parent,
35                         const char* message
36                         )
37 {
38   char* cbuf = cwa_buffer_provide (256 /* just a good guess */ +
39                                    2*(strlen (repo->query->name) + strlen (repo->query->email)) +
40                                    strlen (message));
41   sprintf (cbuf,
42            "tree %s\n"
43            "parent %s\n"
44            "author %s <%s> %lu +0000\n"
45            "committer %s <%s> %lu +0000\n\n%s",
46            sha1_to_hex (sha1_tree),
47            sha1_to_hex (sha1_parent),
48            repo->query->name,
49            repo->query->email,
50            repo->query->now,
51            repo->query->name,
52            repo->query->email,
53            repo->query->now,
54            message
55            );
56
57   unsigned char sha1[20];
58
59   if (!!write_sha1_file (cbuf, strlen (cbuf), "commit", sha1))
60     die("error writing worktree %s\n", sha1_to_hex (sha1));
61
62   struct ref_lock * lock = lock_ref_sha1 (ref, NULL);
63
64   lock->force_write = 1;
65   return write_ref_sha1 (lock, sha1, NULL);
66 }
67
68
69 void
70 webgit_worktree_setup (struct webgit_repo_info* repo)
71 {
72   char* worktree = cwa_buffer_provide (PATH_MAX);
73   unsigned char sha1_tree[20];
74   snprintf (worktree, PATH_MAX, "refs/worktrees/%s", repo->query->head);
75
76   unsigned char sha1_head[20];
77   get_sha1 (repo->query->head, sha1_head);
78
79   if (!read_ref (worktree, sha1_tree))
80     {
81       /* found worktree */
82       struct commit* commit = lookup_commit_reference (sha1_tree);
83       parse_commit (commit);
84
85       struct commit* treehead = pop_commit (&commit->parents);
86       parse_commit (treehead);
87
88       if (!!hashcmp (sha1_head, treehead->object.sha1))
89         {
90           /* head diverted from worktree */
91
92           if (!strncmp (webgit_object_commit_tree_parse (commit),
93                         webgit_object_commit_tree_parse (treehead), 40))
94             {
95               /* workree unchanged, forward it */
96               struct commit* newhead = lookup_commit_reference (sha1_head);
97               parse_commit (newhead);
98
99               get_sha1_hex (webgit_object_commit_tree_parse (newhead), sha1_tree);
100               webgit_worktree_create (repo, worktree+5, sha1_tree, sha1_head, "");
101             }
102           else
103             /* else uhm */
104             die ("TODO: uh ohh, head diverted from worktree, needs merge strategy");
105         }
106     }
107   else
108     {
109       /* create brand new worktree */
110       struct commit* parent = lookup_commit_reference (sha1_head);
111       parse_commit (parent);
112
113       get_sha1_hex (webgit_object_commit_tree_parse (parent), sha1_tree);
114       webgit_worktree_create (repo, worktree+5, sha1_tree, sha1_head, "");
115     }
116   repo->worktree = cwa_strndup (sha1_to_hex (sha1_tree), 40);
117 }
118
119
120
121
122 #if 0
123 int
124 webgit_worktree_same_blob (struct webgit_repo_info* repo)
125 {
126
127   return 0;
128 }
129 #endif
130
131 /*
132 //      Local Variables:
133 //      mode: C
134 //      c-file-style: "gnu"
135 //      indent-tabs-mode: nil
136 //      End:
137 */