/// <summary> /// Create a checkout class for checking out one tree, merging with the index /// </summary> /// <param name="repo"> </param> /// <param name="root"> workdir </param> /// <param name="index"> current index </param> /// <param name="merge"> tree to check out </param> public WorkDirCheckout(Repository repo, FileSystemInfo root, GitIndex index, Tree merge) : this() { this._repo = repo; this._root = root; this._index = index; this._merge = merge; }
public IndexTreeWalker(GitIndex index, Tree mainTree, Tree newTree, FileSystemInfo root, IndexTreeVisitor visitor) { _mainTree = mainTree; _newTree = newTree; _root = root; _visitor = visitor; _threeTrees = newTree != null; _indexMembers = index.Members; }
public IndexDiff(Tree tree, GitIndex index) { _anyChanges = false; _tree = tree; _index = index; Added = new HashSet<string>(); Changed = new HashSet<string>(); Removed = new HashSet<string>(); Missing = new HashSet<string>(); Modified = new HashSet<string>(); }
private static bool eq(TreeEntry t1, GitIndex.Entry e) { return (Compare(t1, e) == 0); }
private static int Compare(TreeEntry t, GitIndex.Entry i) { if ((t == null) && (i == null)) { return 0; } if (t == null) { return 1; } if (i == null) { return -1; } return Tree.CompareNames(t.FullNameUTF8, i.NameUTF8, TreeEntry.LastChar(t), TreeEntry.LastChar(i)); }
void IndexTreeVisitor.VisitEntry(TreeEntry treeEntry, TreeEntry auxEntry, GitIndex.Entry indexEntry, FileInfo file) { VisitEntryAuxDelegate handler = this.VisitEntryAux; if (handler != null) handler(treeEntry,auxEntry, indexEntry, file); }
/// <summary> /// Run the diff operation. Until this is called, all lists will be empty /// </summary> /// <returns>true if anything is different between index, tree, and workdir</returns> private bool Diff() { var commit = Repository.Head.CurrentCommit; _tree = (commit != null ? commit.Tree : new Core.Tree(Repository)); _index = Repository.Index.GitIndex; _index.RereadIfNecessary(); DirectoryInfo root = _index.Repository.WorkingDirectory; var visitor = new AbstractIndexTreeVisitor { VisitEntryAux = OnVisitEntry }; new IndexTreeWalker(_index, _tree, CreateWorkingDirectoryTree(Repository), root, visitor).Walk(); return AnyDifferences; }
public IndexDiff(Repository repository) { this._tree = repository.MapTree("HEAD"); this._index = repository.Index; }
private void VisitEntry(TreeEntry t1, TreeEntry t2, GitIndex.Entry i) { Debug.Assert(((t1 != null) || (t2 != null)) || (i != null), "Needs at least one entry"); Debug.Assert(_root != null, "Needs workdir"); if ((t1 != null) && (t1.Parent == null)) { t1 = null; } if ((t2 != null) && (t2.Parent == null)) { t2 = null; } FileInfo file = null; if (i != null) { file = new FileInfo(Path.Combine(_root.FullName, i.Name)); } else if (t1 != null) { file = new FileInfo(Path.Combine(_root.FullName, t1.FullName)); } else if (t2 != null) { file = new FileInfo(Path.Combine(_root.FullName, t2.FullName)); } if (((t1 != null) || (t2 != null)) || (i != null)) { if (_threeTrees) { _visitor.VisitEntry(t1, t2, i, file); } else { _visitor.VisitEntry(t1, i, file); } } }
/// <summary> /// /// </summary> /// <param name="treeEntry"></param> /// <param name="wdirEntry">Note: wdirEntry is the non-ignored working directory entry.</param> /// <param name="indexEntry"></param> /// <param name="file">Note: gitignore patterns do not influence this parameter</param> private void OnVisitEntry(TreeEntry treeEntry, TreeEntry wdirEntry, GitIndex.Entry indexEntry, FileInfo file) { //Console.WriteLine(" ----------- "); //if (treeEntry != null) // Console.WriteLine("tree: " + treeEntry.Name); //if (wdirEntry != null) // Console.WriteLine("w-dir: " + wdirEntry.Name); //if (indexEntry != null) // Console.WriteLine("index: " + indexEntry.Name); //Console.WriteLine("file: " + file.Name); string subdir_prefix = !string.IsNullOrEmpty (_root_path) ? _root_path + "/" : null; PathStatus path_status = null; if (indexEntry != null) { if (subdir_prefix != null && !indexEntry.Name.StartsWith (subdir_prefix)) return; // File outside the directory if (treeEntry == null) { path_status = OnAdded(indexEntry.Name, path_status); } if (treeEntry != null && !treeEntry.Id.Equals(indexEntry.ObjectId)) { Debug.Assert(treeEntry.FullName == indexEntry.Name); path_status = OnStaged(indexEntry.Name, path_status); } if (!file.Exists) { path_status = OnMissing(indexEntry.Name, path_status); } if (file.Exists && indexEntry.IsModified(new DirectoryInfo(Repository.WorkingDirectory), Options.ForceContentCheck)) { path_status = OnModified(indexEntry.Name, path_status); } if (indexEntry.Stage != 0) { path_status = OnMergeConflict(indexEntry.Name, path_status); } } else // <-- index entry == null { if (treeEntry != null && subdir_prefix != null && !treeEntry.FullName.StartsWith (subdir_prefix)) return; // File outside the directory if (treeEntry != null && !(treeEntry is Core.Tree)) { path_status = OnRemoved(treeEntry.FullName, path_status); } if (wdirEntry != null) // actually, we should enforce (treeEntry == null ) here too but original git does not, may be a bug. path_status = OnUntracked(wdirEntry.FullName, path_status); } if (Options.PerPathNotificationCallback != null && path_status != null) Options.PerPathNotificationCallback(path_status); }
void IndexTreeVisitor.VisitEntry(TreeEntry treeEntry, GitIndex.Entry indexEntry, FileInfo file) { VisitEntryDelegate handler = VisitEntry; if (handler != null) { handler(treeEntry, indexEntry, file); } }
/// <summary> /// Create a checkout class for merging and checking our two trees and the index. /// </summary> /// <param name="repo"> </param> /// <param name="root"> workdir </param> /// <param name="head"> </param> /// <param name="index"> </param> /// <param name="merge"> </param> public WorkDirCheckout(Repository repo, FileSystemInfo root, Tree head, GitIndex index, Tree merge) : this(repo, root, index, merge) { this._head = head; }
private void ProcessEntry(TreeEntry h, TreeEntry m, GitIndex.Entry i) { ObjectId iId = (i == null ? null : i.ObjectId); ObjectId mId = (m == null ? null : m.Id); ObjectId hId = (h == null ? null : h.Id); string name = (i != null ? i.Name : (h != null ? h.FullName : m.FullName)); if (i == null) { // // I (index) H M Result // ------------------------------------------------------- // 0 nothing nothing nothing (does not happen) // 1 nothing nothing exists use M // 2 nothing exists nothing remove path from index // 3 nothing exists exists use M if (h == null) { _updated.Add(name, mId); } else if (m == null) { Removed.Add(name); } else { _updated.Add(name, mId); } } else if (h == null) { // // clean I==H I==M H M Result // ----------------------------------------------------- // 4 yes N/A N/A nothing nothing keep index // 5 no N/A N/A nothing nothing keep index // // 6 yes N/A yes nothing exists keep index // 7 no N/A yes nothing exists keep index // 8 yes N/A no nothing exists fail // 9 no N/A no nothing exists fail if (m == null || mId.Equals(iId)) { if (HasParentBlob(_merge, name)) { if (i.IsModified(_root, true)) { Conflicts.Add(name); } else { Removed.Add(name); } } } else { Conflicts.Add(name); } } else if (m == null) { // // 10 yes yes N/A exists nothing remove path from index // 11 no yes N/A exists nothing fail // 12 yes no N/A exists nothing fail // 13 no no N/A exists nothing fail // if (hId.Equals(iId)) { if (i.IsModified(_root, true)) { Conflicts.Add(name); } else { Removed.Add(name); } } else { Conflicts.Add(name); } } else { if (!hId.Equals(mId) && !hId.Equals(iId) && !mId.Equals(iId)) { Conflicts.Add(name); } else if (hId.Equals(iId) && !mId.Equals(iId)) { if (i.IsModified(_root, true)) { Conflicts.Add(name); } else { _updated.Add(name, mId); } } } }
internal WorkDirCheckout(Repository repo, FileSystemInfo workDir, GitIndex oldIndex, GitIndex newIndex) : this() { _repo = repo; _root = workDir; _index = oldIndex; _merge = repo.MapTree(newIndex.writeTree()); }
private static bool lt(GitIndex.Entry i, TreeEntry t) { return (Compare(t, i) > 0); }
private static bool lt(TreeEntry h, GitIndex.Entry i) { return (Compare(h, i) < 0); }
private void UpdateDirectoryNotRecursive(string path) { _index = Repository.Index.GitIndex; // Tree that will hold the working dir file entries var wtree = new Core.Tree(Repository._internal_repo); // Get a list of a leaves in the path Tree commitTree = null; var commit = Repository.Head.CurrentCommit; commitTree = commit != null ? commit.Tree : null; if (commitTree != null) commitTree = commitTree[path] as Tree; Dictionary<string,Leaf> commitEntries; if (commitTree != null) commitEntries = commitTree.Leaves.ToDictionary (l => l.Path); else commitEntries = new Dictionary<string, Leaf> (); HashSet<string> visited = new HashSet<string> (); // Compare commited files and working tree files DirectoryInfo dir = new DirectoryInfo (Repository.FromGitPath (path)); if (dir.Exists) { foreach (FileInfo fileInfo in dir.GetFiles ()) { string file = path + "/" + fileInfo.Name; Leaf lf; if (commitEntries.TryGetValue (file, out lf)) { // Remove from the collection. At the end of the loop, entries still remaining in the // collection will be processed as not having a corresponding working dir file commitEntries.Remove (file); } TreeEntry wdirEntry = null; if (!IgnoreHandler.IsIgnored (file) && fileInfo.Exists) wdirEntry = wtree.AddFile (file); GitIndex.Entry indexEntry = _index.GetEntry (file); OnVisitEntry (lf != null ? lf.InternalEntry : null, wdirEntry, indexEntry, fileInfo); visited.Add (file); } } // Now visit entries for which a working dir file was not found foreach (var lf in commitEntries) { string file = lf.Key; FileInfo fileInfo = new FileInfo (Repository.FromGitPath (file)); GitIndex.Entry indexEntry = _index.GetEntry (file); OnVisitEntry (lf.Value.InternalEntry, null, indexEntry, fileInfo); visited.Add (file); } // Finally, visit remaining index entries which are not in the working dir nor in the commit foreach (var ie in _index.Members) { string file = ie.Name; // Exclude entries in subdirectories of _root_path int i = file.LastIndexOf ('/'); string fdir = i != -1 ? file.Substring (0, i) : string.Empty; if (fdir == _root_path && !visited.Contains (file)) OnVisitEntry (null, null, ie, new FileInfo (Repository.FromGitPath (file))); } }
// Methods public IndexTreeWalker(GitIndex index, Tree mainTree, FileSystemInfo root, IndexTreeVisitor visitor) : this(index, mainTree, null, root, visitor) { }
/// <summary> /// Run the diff operation. Until this is called, all lists will be empty /// </summary> /// <returns>true if anything is different between index, tree, and workdir</returns> private void UpdateDirectoryRecursive(string path) { var commit = Repository.Head.CurrentCommit; _tree = (commit != null ? commit.Tree : new Core.Tree(Repository)); _index = Repository.Index.GitIndex; _index.RereadIfNecessary(); DirectoryInfo root = _index.Repository.WorkingDirectory; var visitor = new AbstractIndexTreeVisitor { VisitEntryAux = OnVisitEntry }; new IndexTreeWalker(_index, _tree, CreateWorkingDirectoryTree(path), root, visitor).Walk(); }
public IndexTreeWalker(GitIndex index, Tree mainTree, Tree newTree, DirectoryInfo root, IndexTreeVisitor visitor) { throw new NotImplementedException(); }
private void UpdateSingleFile(string file) { TreeEntry treeEntry = null; var commit = Repository.Head.CurrentCommit; _tree = commit != null ? commit.Tree : null; if (_tree != null) treeEntry = _tree.FindBlobMember (file); _index = Repository.Index.GitIndex; _index.RereadIfNecessary(); GitIndex.Entry indexEntry = _index.GetEntry (file); TreeEntry wdirEntry = null; FileInfo fileInfo = new FileInfo (Path.Combine (Repository.WorkingDirectory, file.Replace ('/', Path.DirectorySeparatorChar))); if (fileInfo.Exists && !IgnoreHandler.IsIgnored(file)) { var tree = new Core.Tree(Repository._internal_repo); wdirEntry = tree.AddFile (file); } OnVisitEntry (treeEntry, wdirEntry, indexEntry, fileInfo); }
public IndexDiff(Tree tree, GitIndex index) { this._tree = tree; this._index = index; }
private void doCheckout(GitSharp.Core.Ref branch) { if (branch == null) throw new ArgumentNullException("branch", "Cannot checkout; no HEAD advertised by remote"); var repo = Repository._internal_repo; if (!Constants.HEAD.Equals(branch.Name)) repo.WriteSymref(Constants.HEAD, branch.Name); GitSharp.Core.Commit commit = repo.MapCommit(branch.ObjectId); RefUpdate u = repo.UpdateRef(Constants.HEAD); u.NewObjectId = commit.CommitId; u.ForceUpdate(); GitIndex index = new GitIndex(repo); GitSharp.Core.Tree tree = commit.TreeEntry; WorkDirCheckout co = new WorkDirCheckout(repo, repo.WorkingDirectory, index, tree); co.checkout(); index.write(); }