Ejemplo n.º 1
0
        void MirrorWorkingTreeFiles(IGitRepo srcRepo, string srcDirPath, string destDirPath)
        {
            if (!Path.IsPathFullyQualified(srcDirPath) ||
                !Path.IsPathFullyQualified(destDirPath))
            {
                throw new InvalidOperationException();
            }

            if (destDirPath == "" || destDirPath == "\\" || destDirPath == "/" || Regex.Match(destDirPath, @"^\w+:\\$").Success)
            {
                throw new InvalidOperationException();
            }

            // 나중에 priority queue 사용을 고려해보는 것으로
            var srcFilePaths  = Directory.GetFiles(srcDirPath);
            var destFilePaths = Directory.EnumerateFiles(destDirPath)
                                .ToHashSet(StringComparer.CurrentCultureIgnoreCase);

            // 1. srcFilePath가 ignored라면 스킵
            var ignoredSrcFilePaths = srcRepo.GetIgnores(srcFilePaths);

            foreach (var srcFilePath in srcFilePaths)
            {
                if (ignoredSrcFilePaths.Contains(srcFilePath))
                {
                    continue;
                }

                var srcFileRelPath = Path.GetRelativePath(srcDirPath, srcFilePath);
                var destFilePath   = Path.Combine(destDirPath, srcFileRelPath);

                // 2. destFile이 있고, 파일 사이즈랑 마지막으로 쓴 시간이 같으면 스킵
                if (destFilePaths.Contains(destFilePath))
                {
                    var srcFileInfo  = new FileInfo(srcFilePath);
                    var destFileInfo = new FileInfo(destFilePath);

                    // 크기와 날짜가 같으면 스킵
                    if (srcFileInfo.Length == destFileInfo.Length && srcFileInfo.LastWriteTime == destFileInfo.LastWriteTime)
                    {
                        destFilePaths.Remove(destFilePath);
                        continue;
                    }
                }

                // 아니라면 덮어씌우기
                File.Copy(srcFilePath, destFilePath, true);

                // destFilePaths에서 삭제
                destFilePaths.Remove(destFilePath);
            }

            // 남은 파일은 src에 없다는 것이므로 삭제, 주의
            foreach (var destFilePath in destFilePaths)
            {
                File.Delete(destFilePath);
                Console.WriteLine("{0}: deleted", destFilePath);
            }
        }
Ejemplo n.º 2
0
        void MirrorWorkingTreeDirectories(IGitRepo srcRepo, string srcDirPath, string destDirPath, bool bTopLevel)
        {
            if (!Path.IsPathFullyQualified(srcDirPath) ||
                !Path.IsPathFullyQualified(destDirPath))
            {
                throw new InvalidOperationException();
            }

            if (destDirPath == "" || destDirPath == "\\" || destDirPath == "/" || Regex.Match(destDirPath, @"^\w+:\\$").Success)
            {
                throw new InvalidOperationException();
            }

            var srcSubDirPaths  = Directory.GetDirectories(srcDirPath);
            var destSubDirPaths = Directory.EnumerateDirectories(destDirPath).ToHashSet(StringComparer.CurrentCultureIgnoreCase);

            var ignoreSrcSubDirPaths = srcRepo.GetIgnores(srcSubDirPaths);

            // 각 디렉토리에서
            foreach (var srcSubDirPath in srcSubDirPaths)
            {
                if (ignoreSrcSubDirPaths.Contains(srcSubDirPath))
                {
                    continue;
                }

                var srcSubDirRelPath = Path.GetRelativePath(srcDirPath, srcSubDirPath);
                var destSubDirPath   = Path.Combine(destDirPath, srcSubDirRelPath);

                // 중요;
                if (bTopLevel && srcSubDirRelPath.Equals(".git", StringComparison.CurrentCultureIgnoreCase))
                {
                    destSubDirPaths.Remove(destSubDirPath);
                    continue;
                }

                // 디렉토리가 존재한다면
                if (destSubDirPaths.Contains(destSubDirPath))
                {
                    MirrorWorkingTree(srcRepo, srcSubDirPath, destSubDirPath, false);
                    destSubDirPaths.Remove(destSubDirPath);
                }
                else
                {
                    Directory.CreateDirectory(destSubDirPath);
                    MirrorWorkingTree(srcRepo, srcSubDirPath, destSubDirPath, false);
                    destSubDirPaths.Remove(destSubDirPath);
                }
            }

            // src에 존재하지 않거나 ignored된 디렉토리는 삭제
            foreach (var destSubDirPath in destSubDirPaths)
            {
                Directory.Delete(destSubDirPath, true);
                Console.WriteLine("{0}: deleted", destSubDirPath);
            }
        }