*
*
*/
+static GitRepo _GitRepo;
+
public class GitRepo : Object
{
-
- public Array<GitMonitorQueue> cmds;
+
+ public Gee.ArrayList<GitMonitorQueue> cmds;
public string name;
public string gitdir;
public Gee.HashMap<string,bool> ignore_files;
public GitBranch currentBranch;
+ public RooTicket? activeTicket;
+
+ public static GitRepo singleton()
+ {
+ if (_GitRepo == null) {
+ _GitRepo = new GitRepo.single();
+ _GitRepo.cache = new Gee.HashMap<string,GitRepo>();
+ }
+ return _GitRepo;
+ }
+
/**
* index of.. matching gitpath..
*/
public static int indexOf( Array<GitRepo> repos, string gitpath) {
// make a fake object to compare against..
- var test_repo = new GitRepo(gitpath);
+ var test_repo = GitRepo.get(gitpath);
for(var i =0; i < repos.length; i++) {
if (repos.index(i).gitdir == test_repo.gitdir) {
}
+ public Gee.HashMap<string,GitRepo> cache;
+
+
public static Array<GitRepo> list()
{
-
+
//if (GitRepo.list_cache != null) {
// unowned Array<GitRepo> ret = GitRepo.list_cache;
// return ret;
//}
-
+ var cache = GitRepo.singleton().cache;
var list_cache = new Array<GitRepo>();
var dir = Environment.get_home_dir() + "/gitlive";
continue;
}
- list_cache.append_val(new GitRepo( sp )) ;
-
+ var rep = GitRepo.get( sp );
+ list_cache.append_val(rep);
}
-}
-
-
-
+ }
+
+ public static GitRepo get(string path)
+ {
+ var cache = GitRepo.singleton().cache;
+ if (cache.has_key(path)) {
+ return cache.get(path);
+ }
+ return new GitRepo(path);
+ }
+
+ private GitRepo.single() {
+ // used to create the signleton
+ }
/**
* constructor:
*
*
*/
- public 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>();
if (!FileUtils.test(this.gitdir , FileTest.IS_DIR)) {
this.gitdir = path; // naked...
}
- this.cmds = new Array<GitMonitorQueue> ();
- //Repo.superclass.constructor.call(this,cfg);
+ this.cmds = new Gee.ArrayList<GitMonitorQueue> ();
+ var cache = GitRepo.singleton().cache;
+ //Repo.superclass.constructor.call(this,cfg);
+ if ( !cache.has_key(path) ) {
+ cache.set( path, this);
+ }
+ this.loadBranches();
+ this.loadActiveTicket();
}
+ public bool is_wip_branch()
+ {
+ return this.currentBranch.name.has_prefix("wip_");
+
+ }
public bool is_autocommit ()
{
return !FileUtils.test(this.gitdir + "/.gitlive-disable-autocommit" , FileTest.EXISTS);
}
+
+ public bool is_auto_branch ()
+ {
+ return FileUtils.test(this.gitdir + "/.gitlive-enable-auto-branch" , FileTest.EXISTS);
+ }
public bool is_autopush ()
{
return !FileUtils.test(this.gitdir + "/.gitlive-disable-autopush" , FileTest.EXISTS);
}
}
+
+
+
+
public string branchesToString()
{
var ret = "";
}
return ret;
+ }
+ public static void doMerges(string action, string ticket_id, string commit_message)
+ {
+ GitMonitor.gitmonitor.stop();
+
+ var commitrevs = "";
+ var sucess = true;
+ foreach(var repo in GitRepo.singleton().cache.values) {
+ if (repo.activeTicket != null && repo.activeTicket.id == ticket_id) {
+ var res = repo.doMerge(action,ticket_id, commit_message);
+ if (!res) {
+ sucess = false;
+ continue;
+ }
+ commitrevs += commitrevs.length > 0 ? " " : "";
+ commitrevs += repo.currentBranch.lastrev;
+ }
+ }
+ if (sucess && action == "CLOSE") {
+ RooTicket.singleton().getById(ticket_id).close(commitrevs);
+ }
+ GitMonitor.gitmonitor.start();
+ }
+
+
+ public bool doMerge(string action, string ticket_id, string commit_message)
+ {
+ // 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 ret = "";
+ if (action == "CLOSE" || action == "LEAVE") {
+
+ try {
+ var oldbranch = this.currentBranch.name;
+ this.setActiveTicket(null, "master");
+ string [] cmd = { "merge", "--squash", oldbranch };
+ this.git( cmd );
+ cmd = { "commit", "-a" , "-m", commit_message };
+ this.git( cmd );
+ this.push();
+ this.loadBranches(); // updates lastrev..
+
+ var notification = new Notify.Notification(
+ "Merged branch %s to master".printf(oldbranch),
+ "",
+ "dialog-information"
+
+ );
+
+ notification.set_timeout(5);
+ notification.show();
+
+ // close ticket..
+ return true;
+
+ } catch (Error e) {
+
+ GitMonitor.gitmonitor.pauseError(e.message);
+ return false;
+ }
+ // error~?? -- show the error dialog...
+ return false;
+ }
+ if (action == "MASTER") {
+ // merge master into ours..
+ try {
+ string[] cmd = { "merge", "master" };
+ this.git( cmd );
+ var notification = new Notify.Notification(
+ "Merged code from master to %s".printf(this.currentBranch.name),
+ "",
+ "dialog-information"
+
+ );
+ notification.set_timeout(5);
+ notification.show();
+
+ return true;
+ } catch (Error e) {
+ GitMonitor.gitmonitor.pauseError(e.message);
+ return false;
+ }
+ }
+ if (action == "EXIT") {
+ try {
+ var oldbranch = this.currentBranch.name;
+ this.setActiveTicket(null, "master");
+ this.loadBranches();
+ var notification = new Notify.Notification(
+ "Left branch %s".printf(oldbranch),
+ "",
+ "dialog-information"
+
+ );
+ notification.set_timeout(5);
+ notification.show();
+
+ return true;
+ } catch (Error e) {
+ GitMonitor.gitmonitor.pauseError(e.message);
+
+ return false;
+ }
+ // error~?? -- show the error dialog...
+
+ }
+ return false;
}
- public void setActiveTicket(RooTicket ticket, string branchname)
+ 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);
+ if (ticket_id.length < 1) {
+ return;
+ }
+ this.activeTicket = RooTicket.singleton().getById(ticket_id);
+
-
}
- public void createBranchNamed(string branchname)
+
+
+ public bool setActiveTicket(RooTicket? ticket, string branchname)
{
- string[] cmd = { "checkout", "-b" , branchname };
- this.git(cmd);
+ 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.activeTicket = ticket;
+ return true;
+ }
+
+ public bool createBranchNamed(string branchname)
+ {
+
+ var stash = false;
+ if (this.branches.has_key(branchname)) {
+ // this is where it get's tricky...
+ try {
+ string[] cmd = { "ls-files" , "-m" }; // list the modified files..
+ var ret = this.git(cmd);
+ stash = ret.length> 1 ;
+
+
+ cmd = { "stash" };
+ if (stash) { this.git(cmd); }
+
+ cmd = { "checkout", branchname };
+ this.git(cmd);
+ } catch(Error e) {
+ GitMonitor.gitmonitor.pauseError(e.message);
+ return false;
+ }
+ try {
+ if (branchname != "master") {
+ string[] cmd = { "merge", "master" };
+ this.git(cmd);
+ this.push();
+ //cmd = { "commit", "-a" , "-m", "merge master changes" };
+ //git chethis.git( cmd );
+ }
+
+ } catch(Error e) {
+ 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(
+ branchname)
+ + e.message
+ );
+ return false;
+
+ }
+ try {
+ string[] cmd = { "stash", "pop" };
+ if (stash) { this.git(cmd); }
+ } catch(Error ee) {
+ GitMonitor.gitmonitor.pauseError(ee.message);
+ return false;
+ }
+ this.push();
+
+ } else {
+ try {
+
+ string[] cmd = { "checkout", "-b" , branchname };
+ this.git(cmd);
+ this.push();
+ cmd = { "branch", "--set-upstream-to=origin/"+branchname , branchname };
+ this.git(cmd);
+
+ } catch(Error ee) {
+ GitMonitor.gitmonitor.pauseError(ee.message);
+ return false;
+ }
+
+ }
+ var notification = new Notify.Notification(
+ "Changed to branch %s".printf(branchname),
+ "",
+ "dialog-information"
+
+ );
+
+ notification.set_timeout(5);
+ notification.show();
+
+
this.loadBranches(); // update branch list...
+ //GitMonitor.gitmonitor.runQueue(); // no point - we have hidden the queue..
+ return true;
}
*
* @argument {Array} files the files to add.
*/
- public string add ( Array<GitMonitorQueue> files ) throws Error, SpawnError
+ public string add ( Gee.ArrayList<GitMonitorQueue> files ) throws Error, SpawnError
{
// should really find out if these are untracked files each..
// we run multiple versions to make sure that if one failes, it does not ignore the whole lot..
// not sure if that is how git works.. but just be certian.
var ret = "";
- for (var i = 0; i < files.length;i++) {
- var f = files.index(i).vname;
+ for (var i = 0; i < files.size;i++) {
+ var f = files.get(i).vname;
try {
string[] cmd = { "add", f };
this.git( cmd );
*
* @argument {Array} files the files to add.
*/
- public string remove ( Array<GitMonitorQueue> files ) throws Error, SpawnError
+ public string remove ( Gee.ArrayList<GitMonitorQueue> files ) throws Error, SpawnError
{
// this may fail if files do not exist..
// should really find out if these are untracked files each..
// not sure if that is how git works.. but just be certian.
var ret = "";
- for (var i = 0; i < files.length;i++) {
- var f = files.index(i).vname;
+ for (var i = 0; i < files.size;i++) {
+ var f = files.get(i).vname;
try {
string[] cmd = { "rm", "-f" , f };
this.git( cmd );
*
*/
- public string commit ( string message, Array<GitMonitorQueue> files ) throws Error, SpawnError
+ public string commit ( string message, Gee.ArrayList<GitMonitorQueue> files ) throws Error, SpawnError
{
*/
string[] args = { "commit", "-m" };
args += (message.length > 0 ? message : "Changed" );
- for (var i = 0; i< files.length ; i++ ) {
- args += files.index(i).vname; // full path?
+ for (var i = 0; i< files.size ; i++ ) {
+ args += files.get(i).vname; // full path?
}
return this.git(args);
public string push () throws Error, SpawnError
{
// should
- return this.git({ "push", "origin", "HEAD" });
+ return this.git({ "push", "--all" });
}