public void IsCommitAncestor_returns_false_is_descendant_and_ancestor_are_swapped() { string ancestorId; string descandantId; // create 2 commits on master branch using (var workingDirectory = new TemporaryWorkingDirectory(m_TempDirectory.Location, "master")) { File.WriteAllText(Path.Combine(workingDirectory.Location, "file1.txt"), "Irrelevant"); ancestorId = workingDirectory.Commit("Commit1"); File.WriteAllText(Path.Combine(workingDirectory.Location, "file2.txt"), "Irrelevant"); descandantId = workingDirectory.Commit("Commit1"); workingDirectory.Push(); } Assert.False(m_Repository.IsCommitAncestor(descandantId, ancestorId)); }
public void Repository_with_subdirectories() { // arrange string commitId; using (var workingDirectory = new TemporaryWorkingDirectory(m_Repository.Directory.Location, "master")) { var directory = new Directory(Path.GetFileName(workingDirectory.Location)) { root => new Directory(root, s_Dir1) { dir1 => new EmptyFile(dir1, s_File1), dir1 => new EmptyFile(dir1, s_File2) }, root => new Directory(root, s_Dir2) { dir2 => new EmptyFile(dir2, s_File1) } }; System.IO.File.Delete(Path.Combine(workingDirectory.Location, RepositoryInfoFile.RepositoryInfoFileName)); m_DirectoryCreator.CreateDirectory(directory, Path.GetDirectoryName(workingDirectory.Location)); commitId = workingDirectory.Commit(); workingDirectory.Push(); } using (var repo = new Repository(m_Repository.Directory.Location)) { // act var commit = repo.Lookup<Commit>(commitId); var gitDirectory = new GitDirectory(null, m_Repository.Directory.Name, commit); // assert Assert.Equal(m_Repository.Directory.Name, gitDirectory.Name); Assert.Equal(2, gitDirectory.Directories.Count()); Assert.Empty(gitDirectory.Files); Assert.True(gitDirectory.DirectoryExists(s_Dir1)); Assert.True(gitDirectory.GetDirectory(s_Dir1).FileExists(s_File1)); Assert.True(gitDirectory.GetDirectory(s_Dir1).FileExists(s_File2)); Assert.True(gitDirectory.DirectoryExists(s_Dir2)); Assert.True(gitDirectory.GetDirectory(s_Dir2).FileExists(s_File1)); } }
public void IsCommitAncestor_returns_false_if_commits_are_from_different_branches() { m_Repository.CreateBranch("branch1", m_Repository.Commits.Single()); m_Repository.CreateBranch("branch2", m_Repository.Commits.Single()); string ancestorId; using (var workingDirectory = new TemporaryWorkingDirectory(m_TempDirectory.Location, "branch1")) { File.WriteAllText(Path.Combine(workingDirectory.Location, "file1.txt"), "Irrelevant"); ancestorId = workingDirectory.Commit("Commit1"); workingDirectory.Push(); } string descandantId; using (var workingDirectory = new TemporaryWorkingDirectory(m_TempDirectory.Location, "branch2")) { File.WriteAllText(Path.Combine(workingDirectory.Location, "file1.txt"), "Irrelevant"); descandantId = workingDirectory.Commit("Commit2"); workingDirectory.Push(); } Assert.False(m_Repository.IsCommitAncestor(ancestorId, descandantId)); Assert.False(m_Repository.IsCommitAncestor(descandantId, ancestorId)); }
public void Commit_creates_a_new_commit() { using (var instance = new TemporaryWorkingDirectory(m_MasterRepository.Directory.Location, "master")) { CreateFile(instance, "file2.txt"); var originalCommitCount = GetCommitCount(instance.Location, "master"); instance.Commit(); var newCommitCount = GetCommitCount(instance.Location, "master"); Assert.Equal(originalCommitCount +1, newCommitCount); } }
public void HasChanges_Returns_False_after_Commit() { using (var instance = new TemporaryWorkingDirectory(m_MasterRepository.Directory.Location, "master")) { CreateFile(instance, "file2.txt"); instance.Commit(); Assert.False(instance.HasChanges); } }
public void RemoveItems(IEnumerable<SyncAction> syncActions) { syncActions = syncActions.ToList(); if (!syncActions.Any()) { return; } // make sure all to be updated actions exist (otherwise we cannot remove them) AssertSyncActionsExist(syncActions, true); using (var workingDir = new TemporaryWorkingDirectory(GitGroup.Repository.Info.Path, BranchName.ToString())) { var localDirectory = new LocalDirectory(null, workingDir.Location); // delete the file foreach (var syncAction in syncActions) { PathValidator.EnsureIsRootedPath(syncAction.Path); var directory = localDirectory.GetDirectory(GetRelativeSyncActionDirectoryPath(syncAction)); var file = (ILocalFile) directory.GetFile(SyncActionFile.GetFileName(syncAction)); System.IO.File.Delete(file.Location); } workingDir.Commit($"{nameof(GitSyncActionService)}: Removed {syncActions.Count()} items"); workingDir.Push(); } }
public void UpdateItems(IEnumerable<SyncAction> syncActions) { syncActions = syncActions.ToList(); if (!syncActions.Any()) { return; } // make sure all to be updated actions exist (no need to check the state, this property might have changed) AssertSyncActionsExist(syncActions, false); using (var workingDir = new TemporaryWorkingDirectory(GitGroup.Repository.Info.Path, BranchName.ToString())) { var root = new Directory(null, "root"); foreach (var syncAction in syncActions) { PathValidator.EnsureIsRootedPath(syncAction.Path); // remove existing files for this sync action var filesToDelete = Enum.GetValues(typeof (SyncActionState)).Cast<SyncActionState>() .Where(state => state != syncAction.State) .Select(state => GetRelativeSyncActionDirectoryPath(state, syncAction.Path)) .Select(relativeDirectoryPath => Path.Combine(relativeDirectoryPath, SyncActionFile.GetFileName(syncAction))) .Select(relativePath => Path.Combine(workingDir.Location, relativePath)) .Where(System.IO.File.Exists).ToList(); foreach (var file in filesToDelete) { System.IO.File.Delete(file); } // add a new file var directory = DirectoryHelper.GetOrAddDirectory(root, GetRelativeSyncActionDirectoryPath(syncAction)); directory.Add(d => new SyncActionFile(d, syncAction)); } var localItemCreator = new LocalItemCreator(); localItemCreator.CreateDirectoryInPlace(root, workingDir.Location); workingDir.Commit($"{nameof(GitSyncActionService)}: Updated {syncActions.Count()} items"); workingDir.Push(); } }
public void AddItems(IEnumerable<SyncAction> syncActions) { syncActions = syncActions.ToArray(); if (!syncActions.Any()) { return; } // make sure, the action does not already exist foreach (var action in syncActions) { var exisitingActions = this[action.State, action.Path].Where(a => a.Id == action.Id); if (exisitingActions.Any()) { throw new DuplicateSyncActionException($"A sync action with id {action.Id} already exists"); } } // create the branch if it does not already exist EnsureBranchExists(); // create a file system tree for the actions var root = new Directory(null, "root"); foreach (var syncAction in syncActions) { PathValidator.EnsureIsRootedPath(syncAction.Path); var directory = DirectoryHelper.GetOrAddDirectory(root, GetRelativeSyncActionDirectoryPath(syncAction)); directory.Add(d => new SyncActionFile(d, syncAction)); } // store the actions using (var workingDir = new TemporaryWorkingDirectory(GitGroup.Repository.Info.Path, BranchName.ToString())) { // create the actions on disk var localItemCreator = new LocalItemCreator(); localItemCreator.CreateDirectoryInPlace(root, workingDir.Location); // commit (no check if there are pending changes, because there will always be changes (we made sure that syncActions is not empty and action do not yet exist)) workingDir.Commit($"{nameof(GitSyncActionService)}: Added {syncActions.Count()} items"); workingDir.Push(); } }
public void UpdateItem(SyncFolder folder) { if (folder == null) { throw new ArgumentNullException(nameof(folder)); } if (!ItemExists(folder.Name)) { throw new SyncFolderNotFoundException($"A sync folder named '{folder.Name}' could not be found"); } using (var workingDirectory = new TemporaryWorkingDirectory(GitGroup.Repository.Info.Path, RepositoryInitHelper.ConfigurationBranchName.ToString())) { var syncFoldersPath = Path.Combine(workingDirectory.Location, s_SyncFolders); var filePath = Path.Combine(syncFoldersPath, $"{folder.Name}.{s_Json}"); using (var stream = NativeFile.Open(filePath, FileMode.Open, FileAccess.Write)) { folder.WriteTo(stream); } if (workingDirectory.HasChanges) { try { workingDirectory.Commit($"Updated SyncFolder '{folder.Name}'"); workingDirectory.Push(); } catch (EmptyCommitException) { // no changes after all (HasChanges does not seem to be a 100% accurate) // => ignore exception } } } }
public void AddItem(ISyncPoint state) { if (state == null) { throw new ArgumentNullException(nameof(state)); } if (ItemExists(state.Id)) { throw new DuplicateSyncPointException(state.Id); } // create synchronization state branch if necessary EnsureBranchExists(); var directory = new Directory(null, s_DirectoryName) { d => new SyncPointStateFile(d, state) }; using (var workingDirectory = new TemporaryWorkingDirectory(GitGroup.Repository.Info.Path, BranchName.ToString())) { var localItemCreator = new LocalItemCreator(); localItemCreator.CreateDirectory(directory, workingDirectory.Location); workingDirectory.Commit($"{nameof(GitSyncPointService)}: Added SyncPoint {state.Id}"); workingDirectory.Push(); } }
public void GetChangedFiles_ignores_Changes_outside_of_the_Snapshot_directory() { //ARRANGE var state1 = new Directory(s_Dir1); var state2 = new Directory(s_Dir1) { dir1 => new EmptyFile(dir1, "file1") }; var snapshot1 = m_Instance.CreateSnapshot(state1); // create unrelated change between two snapshots using (var workingDirectory = new TemporaryWorkingDirectory(m_Repository.Info.Path, m_Instance.Id)) { NativeFile.WriteAllText(Path.Combine(workingDirectory.Location, "foo"), "Hello World"); workingDirectory.Commit(); workingDirectory.Push(); } var snapshot2 = m_Instance.CreateSnapshot(state2); Assert.NotEqual(snapshot1.Id, snapshot2.Id); //ACT var changedFiles = m_Instance.GetChangedFiles(snapshot1.Id, snapshot2.Id); //ASSERT Assert.Single(changedFiles); }
public void AddItems(IEnumerable<ConflictInfo> conflicts) { if (conflicts == null) { throw new ArgumentNullException(nameof(conflicts)); } conflicts = conflicts.ToArray(); if(!conflicts.Any()) { return; } EnsureBranchExists(); var exisitngRoot = new GitDirectory(null, "root", GitGroup.Repository.GetLocalBranch(BranchName).Tip); var createdRoot = new Directory(null, "root"); // verify conflicts foreach (var conflict in conflicts) { var relativePath = GetRelativeConflictInfoFilePath(conflict.FilePath); if (exisitngRoot.FileExists(relativePath)) { throw new DuplicateItemException($"A ConflictInfo for '{conflict.FilePath}' already exists"); } var directory = DirectoryHelper.GetOrAddDirectory(createdRoot, PathParser.GetDirectoryName(relativePath)); directory.Add(f => new ConflictInfoFile(f, conflict)); } using (var workingDirectory = new TemporaryWorkingDirectory(GitGroup.Repository.Info.Path, BranchName.ToString())) { var localItemCreator = new LocalItemCreator(); localItemCreator.CreateDirectoryInPlace(createdRoot, workingDirectory.Location); workingDirectory.Commit($"{nameof(GitConflictService)}: Added {conflicts.Count()} items"); workingDirectory.Push(); } }
public void RemoveItems(IEnumerable<ConflictInfo> conflicts) { if (conflicts == null) { throw new ArgumentNullException(nameof(conflicts)); } conflicts = conflicts.ToArray(); if (!conflicts.Any()) { return; } if (!GitGroup.Repository.LocalBranchExists(BranchName)) { throw new ItemNotFoundException($"There is no ConflictInfo for file '{conflicts.First().FilePath}'"); } var root = new GitDirectory(null, "root", GitGroup.Repository.GetLocalBranch(BranchName).Tip); // verify conflicts foreach (var conflict in conflicts) { var relativePath = GetRelativeConflictInfoFilePath(conflict.FilePath); if (!root.FileExists(relativePath)) { throw new ItemNotFoundException($"There is no ConflictInfo for file '{conflict.FilePath}'"); } } // delete conflict info files using (var workingDirectory = new TemporaryWorkingDirectory(GitGroup.Repository.Info.Path, BranchName.ToString())) { var localDirectory= new LocalDirectory(null, workingDirectory.Location); foreach (var conflict in conflicts) { var relativePath = GetRelativeConflictInfoFilePath(conflict.FilePath); System.IO.File.Delete(((ILocalFile)localDirectory.GetFile(relativePath)).Location); } workingDirectory.Commit($"{nameof(GitConflictService)}: Removed {conflicts.Count()} items"); workingDirectory.Push(); } }
public void AddItem(SyncFolder folder) { if (this.Items.Any(f => f.Name.Equals(folder.Name, StringComparison.CurrentCultureIgnoreCase))) { throw new DuplicateSyncFolderException(folder.Name); } // add config file for the sync folder to the configuration directory using (var workingDirectory = new TemporaryWorkingDirectory(GitGroup.Repository.Info.Path, RepositoryInitHelper.ConfigurationBranchName.ToString())) { var syncFoldersPath = Path.Combine(workingDirectory.Location, s_SyncFolders); if (NativeDirectory.Exists(syncFoldersPath) == false) { NativeDirectory.CreateDirectory(syncFoldersPath); } var filePath = Path.Combine(syncFoldersPath, $"{folder.Name}.{s_Json}"); using (var stream = NativeFile.Open(filePath, FileMode.CreateNew, FileAccess.Write)) { folder.WriteTo(stream); } workingDirectory.Commit($"Added SyncFolder '{folder.Name}'"); workingDirectory.Push(); } }
public void Push_transfers_changes_to_master_directory() { var fileName = Path.GetRandomFileName(); using (var instance = new TemporaryWorkingDirectory(m_BareMasterRepository.Directory.Location, "master")) { CreateFile(instance, fileName); instance.Commit(); instance.Push(); } // clone repo again to check if the file we created shows up in new clone using (var workingDirectory = new TemporaryWorkingDirectory(m_BareMasterRepository.Directory.Location, "master")) { Assert.True(IOFile.Exists(Path.Combine(workingDirectory.Location, fileName))); } }
public static GitBasedMultiFileSystemSnapshot Create(Repository repository, BranchName branchName, IHistoryService historyService) { var directoryCreator = new LocalItemCreator(); var branch = repository.GetBranch(branchName); string commitId; using (var workingRepository = new TemporaryWorkingDirectory(repository.Info.Path, branch.FriendlyName)) { var snapshotDirectory = new Directory(null, s_SnapshotDirectoryName); foreach (var fileSystemHistory in historyService.Items) { var fileName = fileSystemHistory.Name + s_FileNameSuffix; var content = fileSystemHistory.LatestFileSystemSnapshot?.Id ?? ""; snapshotDirectory.Add(d => new TextFile(d, fileName, content)); } var snapshotDirectoryPath = Path.Combine(workingRepository.Location, s_SnapshotDirectoryName); directoryCreator.CreateDirectoryInPlace(snapshotDirectory, snapshotDirectoryPath, true); if (workingRepository.HasChanges) { try { commitId = workingRepository.Commit("Created multi-filesystem snapshot"); workingRepository.Push(); } catch (EmptyCommitException) { // no changes after all (HasChanges does not seem to be a 100% accurate) commitId = repository.GetBranch(branchName).Tip.Sha; } } else { commitId = repository.GetBranch(branchName).Tip.Sha; } } var commit = repository.Lookup<Commit>(commitId); return IsSnapshot(commit) ? new GitBasedMultiFileSystemSnapshot(commit, historyService) : null; }
public void HasChanges_Returns_True_if_a_file_was_modified() { using (var instance = new TemporaryWorkingDirectory(m_MasterRepository.Directory.Location, "master")) { var filePath = Path.Combine(instance.Location, s_File1); IOFile.WriteAllText(filePath, "Hello_World"); Assert.True(instance.HasChanges); instance.Commit(); Assert.False(instance.HasChanges); IOFile.WriteAllText(filePath, "Hello World"); Assert.True(instance.HasChanges); } }
/// <summary> /// Adds the specified file to the specified branch using the path of the transaction's local repository /// </summary> protected void AddFile(IGitTransaction transaction, string branchName, string fileName) { using (var workingDirectory = new TemporaryWorkingDirectory(transaction.LocalPath, branchName)) { var path = Path.Combine(workingDirectory.Location, fileName); File.WriteAllText(path, "Some file content"); workingDirectory.Commit(); workingDirectory.Push(); } }