Fixed staging
authorChristian Thaeter <ct@pipapo.org>
Wed, 19 Mar 2008 12:09:38 +0000 (13:09 +0100)
committerChristian Thaeter <ct@pipapo.org>
Wed, 19 Mar 2008 12:09:38 +0000 (13:09 +0100)
Covert lineendings back to unix style when the original file was unix style

src/actions.c
src/worktree.c
src/worktree.h

index 7ca657d..6e796c1 100644 (file)
@@ -667,8 +667,24 @@ webgit_stage_action (struct webgit_query* query)
 static Html
 webgit_commit_action (struct webgit_query* query)
 {
-  (void) query;
-  return html("TODO: commit");
+  query->current_repo =  webgit_repo_enter (query);
+
+  /* stage pending changes */
+  webgit_worktree_stage (query->current_repo);
+
+  /* create diff head->worktree */
+  unsigned char sha1_worktree[20];
+  if (query->current_repo->worktree)
+    get_sha1_hex (query->current_repo->worktree, sha1_worktree);
+  else
+    webgit_err ("no worktree");
+
+  unsigned char sha1_head[20];
+  get_sha1 (query->head, sha1_head);
+  struct commit* head_commit = lookup_commit (sha1_head);
+  parse_commit (head_commit);
+
+  return webgit_diff_table_trees (query, head_commit->tree->object.sha1, sha1_worktree);
 }
 
 
index 4cce9ee..243cfb5 100644 (file)
@@ -137,7 +137,7 @@ int
 webgit_worktree_getsha1 (struct webgit_query* query, unsigned char* sha1)
 {
   unsigned char sha1_tree[20];
-  if (get_sha1 (query->current_repo->worktree, sha1_tree))
+  if (!query->current_repo->worktree || get_sha1 (query->current_repo->worktree, sha1_tree))
     return 0;
 
   llist worktree;
@@ -192,9 +192,14 @@ webgit_worktree_create (struct webgit_repo_info* repo,
                         const char* message
                         )
 {
+  TRACE (webgit);
+  if (!repo->query->name || !repo->query->email)
+    return 0;
+
   char* cbuf = cwa_buffer_provide (256 /* just a good guess */ +
                                    2*(strlen (repo->query->name) + strlen (repo->query->email)) +
-                                   strlen (message));
+                                   (message ? strlen (message) : 0));
+
   sprintf (cbuf,
            "tree %s\n"
            "parent %s\n"
@@ -227,6 +232,7 @@ webgit_worktree_create (struct webgit_repo_info* repo,
 void
 webgit_worktree_setup (struct webgit_repo_info* repo)
 {
+  TRACE (webgit);
   char* worktree = cwa_buffer_provide (PATH_MAX);
   unsigned char sha1_tree[20];
   snprintf (worktree, PATH_MAX, "refs/worktrees/%s", repo->query->head);
@@ -277,6 +283,7 @@ webgit_worktree_setup (struct webgit_repo_info* repo)
 void
 webgit_worktree_removefile (LList tree, const char* path)
 {
+  TRACE (webgit);
   const char* delim  = strchr (path, '/');
   size_t len = delim ? (size_t)(delim - path - 1) : strlen (path);
 
@@ -306,6 +313,7 @@ webgit_worktree_removefile (LList tree, const char* path)
 void
 webgit_worktree_addfile (LList tree, const char* path, unsigned char* sha1)
 {
+  TRACE (webgit);
   const char* delim  = strchr (path, '/');
   size_t len = delim ? (size_t)(delim - path - 1) : strlen (path);
 
@@ -331,9 +339,45 @@ webgit_worktree_addfile (LList tree, const char* path, unsigned char* sha1)
 }
 
 
+static int
+webgit_worktree_isunix (LList tree, const char* path)
+{
+  TRACE (webgit);
+  const char* delim  = strchr (path, '/');
+  size_t len = delim ? (size_t)(delim - path - 1) : strlen (path);
+
+  LLIST_FOREACH (tree, n)
+    {
+      struct treenode* node = (struct treenode*)n;
+
+      if (!strncmp (node->name, path, len))
+        {
+          if (!delim)
+            {
+              size_t size;
+              char* buf = read_object_with_reference (node->sha1, "blob", &size, NULL);
+              if (!memchr(buf, 0, size) && !memchr (buf, '\r', size))
+                return 1;
+              return 0;
+            }
+          else
+            {
+              /*enter subtree*/
+              if (llist_is_empty (&node->subtree))
+                webgit_tree_parse (&node->subtree, node->sha1);
+              return webgit_worktree_isunix (&node->subtree, delim+1);
+            }
+        }
+    }
+  NOTREACHED;
+  return -1;
+}
+
+
 void
 webgit_worktree_fixup (LList tree, unsigned char* sha1)
 {
+  TRACE (webgit);
   size_t size = 0;
   LLIST_FOREACH (tree, n)
     {
@@ -379,6 +423,7 @@ webgit_worktree_fixup (LList tree, unsigned char* sha1)
 void
 webgit_worktree_stage (struct webgit_repo_info* repo)
 {
+  TRACE (webgit);
   struct webgit_query* query = repo->query;
 
   /* add blob/file to repo */
@@ -396,12 +441,8 @@ webgit_worktree_stage (struct webgit_repo_info* repo)
       data_size = query->blob_size;
     }
   else
-    die ("no data");
-
-  unsigned char sha1_blob[20];
-
-  if (!!write_sha1_file (data, data_size, "blob", sha1_blob))
-    die("error writing blob %s\n", sha1_to_hex (sha1_blob));
+    /* no data */
+    return;
 
   /* get original tree */
   char* worktree = cwa_buffer_provide (PATH_MAX);
@@ -423,6 +464,16 @@ webgit_worktree_stage (struct webgit_repo_info* repo)
   llist_init (&tree);
   webgit_tree_parse (&tree, commit->tree->object.sha1);
 
+  /* convert blob to to unix lineendings if the old blob used them too */
+  if (webgit_worktree_isunix (&tree, query->oldpath))
+    data_size = cwa_httptounix (data, data_size);
+
+  /* save new blob */
+  unsigned char sha1_blob[20];
+
+  if (!!write_sha1_file (data, data_size, "blob", sha1_blob))
+    die("error writing blob %s\n", sha1_to_hex (sha1_blob));
+
   /* modify tree */
   if (!strcmp (query->mode, "rename"))
     {
@@ -431,12 +482,10 @@ webgit_worktree_stage (struct webgit_repo_info* repo)
     }
   else if (!strcmp (query->mode, "copy"))
     {
-      die ("copy");
       webgit_worktree_addfile (&tree, query->path, sha1_blob);
     }
   else if (!strcmp (query->mode, "delete"))
     {
-      die ("delete");
       webgit_worktree_removefile (&tree, query->oldpath);
     }
   else
@@ -450,14 +499,23 @@ webgit_worktree_stage (struct webgit_repo_info* repo)
   char* oldcomment = strstr (commit->buffer, "\n\n");
   size_t comment_len = 0;
   if (oldcomment)
-    comment_len = strlen (oldcomment+2);
+    {
+      oldcomment += 2;
+      comment_len = strlen (oldcomment);
+    }
 
   if (query->comment)
       comment_len += (sizeof (" * \n") + strlen (query->comment) - 1);
 
-  char* newcomment = cwa_buffer_provide (comment_len+1);
+  char* newcomment;
 
-  sprintf (newcomment, "%s * %s\n%c", oldcomment ? oldcomment+2 : "", query->comment, '\0');
+  if (query->comment)
+    {
+      newcomment = cwa_buffer_provide (comment_len+1);
+      sprintf (newcomment, "%s * %s\n%c", oldcomment ? oldcomment : "", query->comment, '\0');
+    }
+  else
+    newcomment = oldcomment;
 
   webgit_worktree_create (repo,
                           worktree + 5,
@@ -472,6 +530,7 @@ webgit_worktree_stage (struct webgit_repo_info* repo)
 int
 webgit_worktree_blob_eq (struct webgit_repo_info* repo, const char* path)
 {
+  TRACE (webgit);
   /* find out if the current file in head and worktree are the same */
 
   /* worktree */
index 7d17e7e..664d88a 100644 (file)
@@ -31,6 +31,9 @@ webgit_worktree_getsha1 (struct webgit_query* query, unsigned char* sha1);
 int
 webgit_worktree_blob_eq (struct webgit_repo_info* repo, const char* path);
 
+void
+webgit_worktree_stage (struct webgit_repo_info* repo);
+
 #endif
 /*
 //      Local Variables: