Allow editing only when worktree is not diverted from head
authorChristian Thaeter <ct@pipapo.org>
Thu, 21 Feb 2008 01:59:31 +0000 (02:59 +0100)
committerChristian Thaeter <ct@pipapo.org>
Thu, 21 Feb 2008 01:59:31 +0000 (02:59 +0100)
in case a file got edited and staged previously only a 'diff' link will be
shown.

src/object_blob.c
src/object_tree.c
src/worktree.c
src/worktree.h

index 3601650..ce48a88 100644 (file)
@@ -22,6 +22,7 @@
 #include "actions.h"
 #include "repo.h"
 #include "summary.h"
+#include "worktree.h"
 
 /*
   Display blobs
@@ -43,15 +44,18 @@ webgit_object_blob_menu_action (struct webgit_repo_info* repo, unsigned char* sh
                // TODO: "blame <br />",
                // TODO: "Back to tree <br />",
                // TODO: ,
-               repo->worktree ?
-                webgit_object_link (query, html ("Edit <br />"),
-                                   "repo", query->repo,
-                                   "ref", query->head,
-                                   "commit", query->commit,
-                                   "path", query->path,
-                                    /* "object", worktree_object_get () */
-                                    "action", "edit")
-               : html ("TODO difflink this/worktree <br />"),
+               repo->worktree
+               ? ( webgit_worktree_blob_eq (repo, query->path)
+                   ?  webgit_object_link (query,
+                                          html ("Edit<br />"),
+                                          "repo", query->repo,
+                                          "ref", query->head,
+                                          "commit", query->commit,
+                                          "path", query->path,
+                                          "action", "edit")
+                   : html ("diff<br />")
+                   )
+               : html (),
                webgit_object_tree_parent_link (query, "<<%s"),
                webgit_summary_link (query, repo, html("Summary")), "<br />",
                webgit_main_link (query, html ("Main"))
index 377b3f4..c2015be 100644 (file)
@@ -22,6 +22,7 @@
 #include "actions.h"
 #include "repo.h"
 #include "summary.h"
+#include "worktree.h"
 
 Html
 webgit_object_tree_parent_link (struct webgit_query* query, char* fmt)
@@ -179,19 +180,22 @@ webgit_html_tree (const unsigned char *sha1, const char *base, int baselen,
                                                               "path", pathname,
                                                               "action", "raw"),
                                           repo_in_flight->worktree
-                                          ? html (
-                                                  " ",
-                                                  webgit_object_link (query, html ("edit"),
-                                                                      "repo", query->repo,
-                                                                      "ref", query->head,
-                                                                      "commit", query->commit,
-                                                                      "path", pathname,
-                                                                      "action", "edit")
-                                                  )
+                                          ? ( webgit_worktree_blob_eq (repo_in_flight, pathname)
+                                              ? html (
+                                                      " ",
+                                                      webgit_object_link (query, html ("edit"),
+                                                                          "repo", query->repo,
+                                                                          "ref", query->head,
+                                                                          "commit", query->commit,
+                                                                          "path", pathname,
+                                                                          "action", "edit")
+                                                      )
+                                              : html (" diff")
+                                              )
                                           : html ()
-                                          )
-                                    ),
-                              html_nl()
+                                          ),
+                                    html_nl()
+                                    )
                               )
                         );
     }
index b410f4c..88070a1 100644 (file)
@@ -71,6 +71,8 @@ void
 treenode_free (struct treenode* self)
 {
   llist_unlink (&self->node);
+  LLIST_WHILE_HEAD (&self->subtree, node)
+    treenode_free ((struct treenode*) node);
   free (self);
 }
 
@@ -89,7 +91,7 @@ LList
 tree_sort (LList tree)
 {
   llist_sort (tree, treenode_cmp);
- return tree;
 return tree;
 }
 
 static LList tree_in_flight = NULL;
@@ -319,8 +321,6 @@ webgit_worktree_fixup (LList tree, unsigned char* sha1)
   write_sha1_file (buf.buf, buf.len, tree_type, sha1);
 
   strbuf_release (&buf);
-
-  webgit_warn ("written tree %s", sha1_to_hex(sha1));
 }
 
 void
@@ -361,7 +361,6 @@ webgit_worktree_stage (struct webgit_repo_info* repo)
   parse_commit (commit);
 
   struct commit* treehead = pop_commit (&commit->parents);
-  webgit_warn ("parent %p parsed %d\n", treehead, treehead->object.parsed);
 
   parse_commit (treehead);
   unsigned char sha1_parent[20];
@@ -392,6 +391,9 @@ webgit_worktree_stage (struct webgit_repo_info* repo)
 
   webgit_worktree_fixup (&tree, sha1_tree);
 
+  LLIST_WHILE_HEAD (&tree, node)
+    treenode_free ((struct treenode*) node);
+
   char* oldcomment = strstr (commit->buffer, "\n\n");
   size_t comment_len = 0;
   if (oldcomment)
@@ -413,14 +415,99 @@ webgit_worktree_stage (struct webgit_repo_info* repo)
 }
 
 
-#if 0
+
 int
-webgit_worktree_same_blob (struct webgit_repo_info* repo)
+webgit_worktree_blob_eq (struct webgit_repo_info* repo, const char* path)
 {
+  /* find out if the current file in head and worktree are the same */
 
-  return 0;
+  /* worktree */
+  unsigned char sha1_tree[20];
+  get_sha1 (repo->worktree, sha1_tree);
+
+  llist worktree;
+  llist_init (&worktree);
+  webgit_tree_parse (&worktree, sha1_tree);
+
+  const char* delim;
+  const char* name = path;
+  LList tree = &worktree;
+
+  unsigned char* worktree_file = NULL;
+
+  do
+    {
+      delim = strchr (name, '/');
+      size_t len = delim ? (size_t)(delim - name - 1) : strlen (name);
+      LLIST_FOREACH (tree, n)
+        {
+          struct treenode* node = (struct treenode*)n;
+
+          if (strncmp (name, node->name, len))
+            continue;
+          else
+            {
+              if (delim)
+                {
+                  name = delim + 1;
+                  tree = webgit_tree_parse (&node->subtree, node->sha1);
+                  break;
+                }
+              else
+                worktree_file = node->sha1;
+            }
+        }
+    } while (delim);
+
+  /* head */
+  unsigned char sha1_head[20];
+  get_sha1 (repo->query->head, sha1_head);
+  struct commit* head_commit = lookup_commit (sha1_head);
+  parse_commit (head_commit);
+
+  llist headtree;
+  llist_init (&headtree);
+  webgit_tree_parse (&headtree, head_commit->tree->object.sha1);
+
+  name = path;
+  tree = &headtree;
+  unsigned char* headtree_file = NULL;
+
+  do
+    {
+      delim = strchr (name, '/');
+      size_t len = delim ? (size_t)(delim - name - 1) : strlen (name);
+      LLIST_FOREACH (tree, n)
+        {
+          struct treenode* node = (struct treenode*)n;
+          if (strncmp (name, node->name, len))
+            continue;
+          else
+            {
+              if (delim)
+                {
+                  name = delim + 1;
+                  tree = webgit_tree_parse (&node->subtree, node->sha1);
+                  break;
+                }
+              else
+                headtree_file = node->sha1;
+            }
+        }
+    } while (delim);
+
+  int ret = 0;
+
+  if (worktree_file && headtree_file && !hashcmp(worktree_file, headtree_file))
+    ret = 1;
+
+  LLIST_WHILE_HEAD (&worktree, node)
+    treenode_free ((struct treenode*) node);
+  LLIST_WHILE_HEAD (&headtree, node)
+    treenode_free ((struct treenode*) node);
+
+  return ret;
 }
-#endif
 
 /*
 //      Local Variables:
index f7dd980..2ebd425 100644 (file)
@@ -26,10 +26,8 @@ void
 webgit_worktree_setup (struct webgit_repo_info* repo);
 
 
-#if 0
 int
-webgit_worktree_same_blob (struct webgit_repo_info* repo);
-#endif
+webgit_worktree_blob_eq (struct webgit_repo_info* repo, const char* path);
 
 #endif
 /*