Fix #5633 - preview diffs before merge
[gitlive] / GitRepo.vala
index b444ce4..08b3824 100644 (file)
@@ -19,6 +19,7 @@ public class GitRepo : Object
     public string git_working_dir;
     public bool debug = false;
     public bool has_local_changes = false;
+    public string host = "";
     public string git_status;    
     public string git_diff;        
     public string ahead_or_behind = "";
@@ -28,6 +29,7 @@ public class GitRepo : Object
     public Gee.HashMap<string,GitBranch> branches; // accessed in GitBranch..
        public RooTicket? activeTicket;
     public  Gee.HashMap<string,GitRepo> cache;
+    public  Gee.HashMap<string,string> config_cache;
     
     
     
@@ -131,9 +133,7 @@ public class GitRepo : Object
         }
     
         return list_cache;
-        
          
-          
        }
        
        public static GitRepo get(string path) 
@@ -156,7 +156,8 @@ public class GitRepo : Object
      *
      */
      
-    private GitRepo(string path) {
+    private GitRepo(string path) 
+    {
         // cal parent?
         this.name =   File.new_for_path(path).get_basename();
         this.ignore_files = new Gee.HashMap<string,bool>();
@@ -173,79 +174,110 @@ public class GitRepo : Object
                if ( !cache.has_key(path) ) {
                        cache.set( path, this);
        }
+       
+       var r = this.git({ "remote" , "get-url" , "--push" , "origin"});
+       var uri = new Soup.URI(r);      
+       this.host = uri.get_host();
+               this.init_config();
+       
        this.loadBranches();
        this.loadActiveTicket();
        this.loadStatus();
     } 
     
-    public bool is_wip_branch()
+    public bool is_master_branch()
     {
-       return this.currentBranch.name.has_prefix("wip_");
+       // special branches that do not allow autopushing now...
+       return this.currentBranch.name == "master" || this.currentBranch.name == "roojs";
                
     }
+    public void init_config()
+    {
+       this.config_cache = new Gee.HashMap<string,string>();
+       // managed = 
+       if (this.get_config("managed") == "") {
+               this.set_config("managed", this.host == "git.roojs.com" ? "1" : "0");
+               }
+       if (this.get_config("autocommit") == "") {
+               this.set_config("autocommit", this.host == "git.roojs.com" ? "1" : "0");
+               }
+       if (this.get_config("autopush") == "") {
+               this.set_config("autopush", this.host == "git.roojs.com" ? "1" : "0");
+               }
+               
+    }
     
-    public bool is_autocommit ()
+    
+    
+    public string get_config(string key) {
+    
+       if (this.config_cache.has_key(key)) {
+               //GLib.debug("get_config %s = '%s'", key, this.config_cache.get(key));
+               return this.config_cache.get(key);
+               }
+       try {
+               var ret =   this.git({ "config" , "gitlive." + key }).strip();
+               this.config_cache.set(key, ret);
+               //GLib.debug("get_config %s = '%s'", key, ret);
+               return ret;
+       } catch (Error e) {
+               this.config_cache.set(key, "");
+               //GLib.debug("get_config (fail) %s = '%s'", key, "");
+               return ""; // happens when there is nothing set...
+       }
+
+       }
+    public void set_config(string key, string value) {
+       this.git({ "config" , "gitlive." + key, value });
+       this.config_cache.set(key,value);
+       }
+    
+    public bool is_managed()
     {
-       return !FileUtils.test(this.gitdir + "/.gitlive-disable-autocommit" , FileTest.EXISTS);
+       return this.get_config("managed") == "1";
+    }
+    
+    
+    public bool is_autocommit ()
+    {          
+       return this.get_config("autocommit") == "1";            
     }
+    
     public void set_autocommit(bool val)
     {
-
-               var cur = this.is_autocommit();
-               GLib.debug("SET auto commit : %s <= %s", val ? "ON" : "OFF",  cur  ? "ON" : "OFF");
-               if (cur == val) {
-                       return; // no change..
-               }
-               if (!val) {
-                       FileUtils.set_contents(this.gitdir + "/.gitlive-disable-autocommit" , "x");
-               } else {
-                       // it exists...
-                       FileUtils.remove(this.gitdir + "/.gitlive-disable-autocommit" ); 
-               }
+               this.set_config("autocommit", val ? "1" : "0");
     
     }
     
     public bool is_auto_branch ()
     {
-       return FileUtils.test(this.gitdir + "/.gitlive-enable-auto-branch" , FileTest.EXISTS);
+       if (this.name == "gitlog") {
+               return false;
+               }
+               // check remote...
+       if (this.is_managed()) {
+               return true;
+               }
+       return false;
+       
     }
     
     public void set_auto_branch(bool val)
     {
-
-               var cur = this.is_auto_branch();
-               GLib.debug("SET auto branch : %s <= %s", val ? "ON" : "OFF",  cur  ? "ON" : "OFF");
-               
-               if (cur == val) {
-                       return; // no change..
-               }
-               if (val) {
-                       FileUtils.set_contents(this.gitdir + "/.gitlive-enable-auto-branch" , "x");
-               } else {
-                       // it exists...
-                       FileUtils.remove(this.gitdir + "/.gitlive-enable-auto-branch" ); 
+               if (this.name == "gitlog") {
+               return;
                }
+               this.set_config("managed", val ? "1" : "0");
     
     }
     public bool is_autopush ()
     {
-       return !FileUtils.test(this.gitdir + "/.gitlive-disable-autopush" , FileTest.EXISTS);
+       return this.get_config("autopush") == "1";
     }
     public void set_autopush(bool val)
     {
-
-               var cur = this.is_autopush();
-               GLib.debug("SET auto push : %s <= %s", val ? "ON" : "OFF",  cur  ? "ON" : "OFF");
-               if (cur == val) {
-                       return; // no change..
-               }
-               if (!val) {
-                       FileUtils.set_contents(this.gitdir + "/.gitlive-disable-autopush" , "");
-               } else {
-                       // it exists...
-                       FileUtils.remove(this.gitdir + "/.gitlive-disable-autopush" ); 
-               }
-    
+               this.set_config("autopush", val ? "1" : "0");
     }
     
     
@@ -266,11 +298,21 @@ public class GitRepo : Object
     
     public void loadBranches()
     {
+
        GitBranch.loadBranches(this);
     }
      
     
-    
+    public bool hasBranchCalled(string name)
+    {
+       foreach( var br in this.branches.values) {
+                       if (br.name == name) {
+                               return true;
+                       }
+
+               }
+               return false;
+    }
     
     public string branchesToString()
     {
@@ -314,12 +356,14 @@ public class GitRepo : Object
     {
        // in theory we should check to see if other repo's have got the same branch and merge all them at the same time.
        // also need to decide which branch we will merge into?
+                       var master = this.hasBranchCalled("roojs") ? "roojs" : "master";
+       
                   var ret = "";
                   if (action == "CLOSE" || action == "LEAVE") {
                                   
                try {
                    var oldbranch = this.currentBranch.name;
-                   this.setActiveTicket(null, "master");
+                   this.setActiveTicket(null, master);
                           string [] cmd = { "merge",   "--squash",  oldbranch };
                           this.git( cmd );
                           cmd = { "commit",   "-a" , "-m",  commit_message };
@@ -328,7 +372,7 @@ public class GitRepo : Object
                           this.loadBranches(); // updates lastrev..
                
                       var notification = new Notify.Notification(
-                               "Merged branch %s to master".printf(oldbranch),
+                               "Merged branch %s to %s".printf(oldbranch, master),
                                "",
                                 "dialog-information"
                                
@@ -351,10 +395,10 @@ public class GitRepo : Object
        if (action == "MASTER") {
                // merge master into ours..
                        try {
-                       string[] cmd = { "merge",  "master" };
+                       string[] cmd = { "merge", master};
                        this.git( cmd );
                        var notification = new Notify.Notification(
-                                       "Merged code from master to %s".printf(this.currentBranch.name),
+                                       "Merged code from %s to %s".printf(master,this.currentBranch.name),
                                        "",
                                         "dialog-information"
                                        
@@ -371,7 +415,7 @@ public class GitRepo : Object
        if (action == "EXIT") {
                        try {
                        var oldbranch  = this.currentBranch.name;
-                         this.setActiveTicket(null, "master");
+                         this.setActiveTicket(null, master);
                        this.loadBranches();
                        var notification = new Notify.Notification(
                                        "Left branch %s".printf(oldbranch),
@@ -397,11 +441,8 @@ public class GitRepo : Object
     public void loadActiveTicket()
     {
        this.activeTicket = null;
-       if (!FileUtils.test(this.gitdir + "/.gitlive-active-ticket" , FileTest.EXISTS)) {
-               return;
-       }
-       string ticket_id;
-       FileUtils.get_contents(this.gitdir + "/.gitlive-active-ticket" , out ticket_id);  
+               var ticket_id = this.get_config("ticket");
+       
        if (ticket_id.length < 1) {
                return;
                }
@@ -414,14 +455,11 @@ public class GitRepo : Object
     
     public bool setActiveTicket(RooTicket? ticket, string branchname)
     {
+       this.set_config("ticket", "");
        if (!this.createBranchNamed(branchname)) {
                return false;
                }
-               if (ticket != null) {
-               FileUtils.set_contents(this.gitdir + "/.gitlive-active-ticket" , ticket.id);
-       } else {
-               FileUtils.remove(this.gitdir + "/.gitlive-active-ticket" );
-       }
+               this.set_config("ticket", ticket == null ? "": ticket.id);
        this.activeTicket = ticket;
        return true;
     }
@@ -454,8 +492,9 @@ public class GitRepo : Object
     }
      bool switchToExistingBranchNamed(string branchname)
      {
+               var master = this.hasBranchCalled("roojs") ? "roojs" : "master";
                var stash = false;
-                                        // this is where it get's tricky...
+               // this is where it get's tricky...
                string files = "";
                try {                   
                                string[] cmd = { "ls-files" ,  "-m" };                   // list the modified files..
@@ -475,15 +514,15 @@ public class GitRepo : Object
                                return false;           
                  }
                try {
-                  if (branchname != "master") {
-                      string[] cmd = { "merge", "master"  };
+                  if (branchname != master) {
+                      string[] cmd = { "merge", master };
                            this.git(cmd);
                            this.push();
                       
                    }
                    
                } catch(Error e) {
-                   string[] cmd = { "checkout", "master"  };
+                   string[] cmd = { "checkout", master  };
                    this.git(cmd);
                        GitMonitor.gitmonitor.pauseError(
                                "Use\n\na) git checkout %s\nb) git mergetool\nc) git commit\nd) git push\n d) stash pop \ne) start gitlive again\n".printf(
@@ -552,6 +591,51 @@ public class GitRepo : Object
                        return true;
      
      }
+     
+     public static string previewMerges(string ticket_id)
+    {
+       var ret = "";
+       foreach(var  repo in GitRepo.singleton().cache.values) {
+           if (repo.activeTicket == null || repo.activeTicket.id != ticket_id) {
+                       continue;
+               }
+                       ret += repo.previewMerge() + "\n\n";
+
+       }
+       return ret;
+
+    }
+     
+     
+     
+     public string previewMerge()
+     {
+        try {                                  
+                       var master = this.hasBranchCalled("roojs") ? "roojs" : "master";
+                       var lines = this.git({"log", master + "...",  "--pretty=format:%H %P" }).split("\n");;
+                       var head = this.git({"log", "-1",  "--pretty=format:%H %P" });
+                       var start = head.split(" ")[0];
+                       var end = "";
+                       for (var i = 0; i < lines.length; i++) {
+                               var cols = lines[i].split(" ");
+                               if (cols.length > 2) {
+                                       end = cols[0];
+                                       break;
+                               }
+                       }
+                       if (end == "") {
+                               var last = lines[lines.length-1];
+                               end = last.split(" ")[1];                               
+                       }
+
+                       return this.git({ "diff" , (end+".."+start), "--no-color" });
+               }  catch(Error ee) {
+                       GitMonitor.gitmonitor.pauseError(ee.message);
+                       return "Error getting diff";            
+               }
+        
+     
+     }
     
     
     
@@ -765,6 +849,8 @@ public class GitRepo : Object
        // may throw error...
         var sp = new Spawn(cfg);
       
+            //GLib.debug( "GOT result: %d" , sp.result);
+      
        // diff output is a bit big..
                if (args_in[0] != "diff") {
                GLib.debug( "GOT: %s" , sp.output);
@@ -846,15 +932,19 @@ public class GitRepo : Object
      
     public static void updateAll(string after)
     {
-                       update_all_after = after;
-               var tr =  GitRepo.singleton().cache;
-                
+               update_all_after = after;
+               var tr =  GitRepo.singleton().cache;
             
-           update_all_total = tr.size;
-           foreach(var repo  in tr.values) {
-                  repo.update_async(updateAllCallback); 
-            } 
-
+        
+       update_all_total = tr.size;
+       foreach(var repo  in tr.values) {
+                       if (!repo.is_managed()) {
+                       update_all_total--;                     
+                               continue;
+                       }
+           repo.update_async(updateAllCallback); 
+        } 
+               GLib.debug("calls total = %d", (int) update_all_total);
     }
     public static void  updateAllCallback(GitRepo repo, int err, string res)
     {
@@ -862,14 +952,19 @@ public class GitRepo : Object
        repo.loadStatus();
        
        update_all_total--;
+               GLib.debug("calls remaining = %d", (int)update_all_total);      
        if (update_all_total > 0 ) {
+
                return;
                }
+               GLib.debug("call after load = %s", update_all_after);    
+               
                switch (update_all_after) {
                        case "show_clones":
                                Clones.singleton().show();
                                break;
                        default:
+                               GLib.debug("Unkown call after load = %s", update_all_after);            
                                break;
                }
                return;