public override int Run(string[] remainingArguments) { var message = Gitlet.Status(); Console.WriteLine(message); return(0); }
/// <summary> /// Fetches the commit that `branch` is on at `remote`. /// It merges that commit into the current branch. /// </summary> public static string Pull(string remote, string branch) { Files.AssertInRepo(); Config.AssertNotBare(); Gitlet.Fetch(remote, branch); return(Gitlet.Merge("FETCH_HEAD")); }
public override int Run(string[] remainingArguments) { var path = remainingArguments[0]; Gitlet.Add(path); return(0); }
public override int Run(string[] remainingArguments) { Gitlet.Init(new InitOptions { Bare = Bare }); return(0); }
public override int Run(string[] remainingArguments) { var options = new LogOptions(); string message = Gitlet.Log(options); Console.WriteLine(message); return(0); }
public override int Run(string[] remainingArguments) { var command = remainingArguments[0]; var name = remainingArguments[1]; var url = remainingArguments[2]; Gitlet.Remote(command, name, url); return(0); }
public override int Run(string[] remainingArguments) { var remote = remainingArguments[0]; var message = Gitlet.Fetch(remote, null); Console.WriteLine(message); return(0); }
public override int Run(string[] remainingArguments) { var repository = remainingArguments[0]; var branch = remainingArguments[1]; var message = Gitlet.Pull(repository, branch); Console.WriteLine(message); return(0); }
public override int Run(string[] remainingArguments) { var options = new CommitOptions { m = Message }; var message = Gitlet.Commit(options); Console.WriteLine(message); return(0); }
public override int Run(string[] remainingArguments) { var path = remainingArguments[0]; var options = new RmOptions { f = Force, r = Recursive }; Gitlet.Rm(path, options); return(0); }
public override int Run(string[] remainingArguments) { var remotePath = remainingArguments[0]; var targetPath = remainingArguments[1]; var message = Gitlet.Clone(remotePath, targetPath, new CloneOptions { Bare = Bare }); Console.WriteLine(message); return(0); }
public static string Clone(string remotePath, string targetPath, CloneOptions options = null) { options = options ?? new CloneOptions(); // Abort if a `remotePath` or `targetPath` not passed. if (remotePath == null) { throw new ArgumentNullException("remotePath"); } if (targetPath == null) { throw new ArgumentNullException("targetPath"); } // Abort if `remotePath` does not exist, or is not a Gitlet // repository. !util.remote(remotePath)(files.inRepo)) if (!Directory.Exists(remotePath) || !Util.Remote <bool>(remotePath)(Files.InRepo)) { throw new Exception("repository " + remotePath + " does not exist"); } // Abort if `targetPath` exists and is not empty. targetPath = Files.Absolute(targetPath); var targetDir = new DirectoryInfo(targetPath); if (targetDir.Exists && targetDir.GetFileSystemInfos().Length > 0) { throw new Exception(targetPath + " already exists and is not empty"); } // Otherwise, do the clone. remotePath = Files.Absolute(remotePath); // If `targetPath` doesn't exist, create it. if (!targetDir.Exists) { targetDir.Create(); } Util.Remote <object>(targetPath)(() => { // Initialize the directory as a Gitlet repository. Gitlet.Init(options); // Set up `remotePath` as a remote called "origin". Gitlet.Remote("add", "origin", Files.Relative(Files.CurrentPath, remotePath)); // Get the hash of the commit that master is pointing at on // the remote repository. var remoteHeadHash = Util.Remote <string>(remotePath)(() => Refs.Hash("master")); // If the remote repo has any commits, that hash will exist. // The new repository records the commit that the passed // `branch` is at on the remote. It then sets master on the // new repository to point at that commit. if (remoteHeadHash != null) { Gitlet.Fetch("origin", "master"); Core.Merge.WriteFastForwardMerge(null, remoteHeadHash); } return(null); }); // Report the result of the clone. return("Cloning into " + targetPath); }
public static string Merge(string @ref) { Files.AssertInRepo(); Config.AssertNotBare(); // Get the `receiverHash`, the hash of the commit that the // current branch is on. var receiverHash = Refs.Hash("HEAD"); // Get the `giverHash`, the hash for the commit to merge into the // receiver commit. var giverHash = Refs.Hash(@ref); // Abort if head is detached. Merging into a detached head is not // supported. if (Refs.IsHeadDetached()) { throw new Exception("unsupported"); } // Abort if `ref` did not resolve to a hash, or if that hash is // not for a commit object. if (giverHash == null || Objects.Type(Objects.Read(giverHash)) != "commit") { throw new Exception(@ref + ": expected commit type"); } // Do not merge if the current branch - the receiver - already has // the giver's changes. This is the case if the receiver and // giver are the same commit, or if the giver is an ancestor of // the receiver. if (Objects.IsUpToDate(receiverHash, giverHash)) { return("Already up-to-date"); } // Get a list of files changed in the working copy. Get a list // of the files that are different in the receiver and giver. If // any files appear in both lists then abort. var paths = Diff.ChangedFilesCommitWouldOverwrite(giverHash); if (paths.Length > 0) { throw new Exception("local changes would be lost\n" + string.Join("\n", paths) + "\n"); } // If the receiver is an ancestor of the giver, a fast forward // is performed. This is possible because there is already a // commit that incorporates all of the giver's changes into the // receiver. if (Core.Merge.CanFastForward(receiverHash, giverHash)) { // Fast forwarding means making the current branch reflect the // commit that `giverHash` points at. The branch is pointed // at `giverHash`. The index is set to match the contents of // the commit that `giverHash` points at. The working copy is // set to match the contents of that commit. Core.Merge.WriteFastForwardMerge(receiverHash, giverHash); return("Fast-forward"); } // If the receiver is not an ancestor of the giver, a merge // commit must be created. // The repository is put into the merge state. The // `MERGE_HEAD` file is written and its contents set to // `giverHash`. The `MERGE_MSG` file is written and its // contents set to a boilerplate merge commit message. A // merge diff is created that will turn the contents of // receiver into the contents of giver. This contains the // path of every file that is different and whether it was // added, removed or modified, or is in conflict. Added files // are added to the index and working copy. Removed files are // removed from the index and working copy. Modified files // are modified in the index and working copy. Files that are // in conflict are written to the working copy to include the // receiver and giver versions. Both the receiver and giver // versions are written to the index. Core.Merge.WriteNonFastForwardMerge(receiverHash, giverHash, @ref); // If there are any conflicted files, a message is shown to // say that the user must sort them out before the merge can // be completed. if (Core.Merge.HasConflicts(receiverHash, giverHash)) { return("Automatic merge failed. Fix conflicts and commit the result."); } return(Gitlet.Commit(new CommitOptions())); }
/// <summary> /// records the commit that `branch` is at on `remote`. // It does not change the local branch. /// </summary> public static string Fetch(string remote, string branch) { Files.AssertInRepo(); // Abort if a `remote` or `branch` not passed. if (remote == null || branch == null) { throw new Exception("unsupported"); } // Abort if `remote` not recorded in config file. if (!Config.Read().Remotes.ContainsKey(remote)) { throw new Exception(remote + " does not appear to be a git repository"); } // Get the location of the remote. var remoteUrl = Files.Absolute(Config.Read().Remotes[remote].Url); // Turn the unqualified branch name into a qualified remote ref // eg `[branch] -> refs/remotes/[remote]/[branch]` var remoteRef = Refs.ToRemoteRef(remote, branch); // Go to the remote repository and get the hash of the commit // that `branch` is on. var newHash = Util.Remote <string>(remoteUrl)(() => Refs.Hash(branch)); // Abort if `branch` did not exist on the remote. if (newHash == null) { throw new Exception("couldn't find remote ref " + branch); } // Otherwise, perform the fetch. // Note down the hash of the commit this repository currently // thinks the remote branch is on. var oldHash = Refs.Hash(remoteRef); // Get all the objects in the remote `objects` directory and // write them. to the local `objects` directory. (This is an // inefficient way of getting all the objects required to // recreate locally the commit the remote branch is on.) var remoteObjects = Util.Remote <string[]>(remoteUrl)(Objects.AllObjects); foreach (var remoteObject in remoteObjects) { Objects.Write(remoteObject); } // Set the contents of the file at // `.gitlet/refs/remotes/[remote]/[branch]` to `newHash`, the // hash of the commit that the remote branch is on. Gitlet.UpdateRef(remoteRef, newHash); // Record the hash of the commit that the remote branch is on // in `FETCH_HEAD`. (The user can call `gitlet merge // FETCH_HEAD` to merge the remote version of the branch into // their local branch. For more details, see // [gitlet.merge()](#section-93).) Refs.Write("FETCH_HEAD", newHash + " branch " + branch + " of " + remoteUrl); // Report the result of the fetch. return (string.Format( "From {0}\nCount {1}\n{2} -> {3}/{2}{4}\n", remoteUrl, remoteObjects.Length, branch, remote, Core.Merge.IsAForceFetch(oldHash, newHash) ? " (forced)" : "")); }