Windows10如何用Java实现GitHub项目的拷贝(从一个文件夹到另一个文件夹)

目录

一,问题描述

1,相关代码如下:

2,复制后的区别如下: 

二,解决方法

1,相关代码如下:

2,运行效果如下:


一,问题描述

最近有一个需求,需要获得一个GitHub项目的不同commit版本,如果每次都从GitHub上拉取代码的话,不仅耗时(对没有翻墙的朋友来说,比如我/(ㄒoㄒ)/~~),而且不好确定具体的commit版本。

于是想根据已经下载下来的一个commit版本,将其复制到不同的文件夹中(直接复制肯定要比从网站上拉取要快,尤其是大型项目),在各自的文件夹中执行git reset --hard HEAD~n来回滚到指定的版本。

然而在用Java信心满满的编写好代码后,发现复制过来的文件夹中不能执行git命令(主要通过refreshWorkspace方法来调用文件复制、文件删除等函数)

1,相关代码如下:

import java.io.*;

public class GitUtil {

    public static long runRollBackGitShell(String projectPath, int num) {
        try {
            long startTime =  System.currentTimeMillis();
            long endTime, usedTime;
            System.out.println("开始执行命令:git reset --hard HEAD~" + num);// 注意这里必须是HEAD~1而不是HEAD^
            String comm = "cmd.exe /c cd " + projectPath + "&& git reset --hard HEAD~" + num;
            Process proc = Runtime.getRuntime().exec(comm);

            int processCode = proc.waitFor();
            if(processCode == 0) {
                System.out.println("命令执行完成");
                endTime =  System.currentTimeMillis();
                // 获取扫描时间
                usedTime = (endTime - startTime) / 1000;
                System.out.println("更新commit数据用时" + usedTime + "s");
                System.out.println("-----------------------------");
                return usedTime;
            } else {
                System.out.println("执行失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return -1;
    }

    public static String runDiffGitShell(String projectPath) {
        Runtime run = Runtime.getRuntime();
        try {
            Process process = run.exec("cmd.exe /c cd " + projectPath + "&& git diff HEAD~1");
            InputStream in = process.getInputStream();
            InputStreamReader reader = new InputStreamReader(in);
            BufferedReader br = new BufferedReader(reader);
            StringBuffer sb = new StringBuffer();
            String message;
            while((message = br.readLine()) != null) {
                sb.append(message + "\n");
            }
            System.out.println(sb);
            return sb.toString();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    //复制文件夹
    public static void copyFolder(File srcFolder, File desFolder) throws IOException {
        //遍历原始文件夹里面的所有文件及文件夹
        File[] files = srcFolder.listFiles();
        for (File srcFile : files) {
            //如果是文件夹
            if (srcFile.isDirectory()){
                //在新的文件夹内创建一个和srcFile文件夹同名文件夹,然后再递归调用,判断文件夹里面的情况,然后做出相应处理
                String srcFileName = srcFile.getName();
                File newFolder = new File(desFolder, srcFileName);
                if (!newFolder.exists()){
                    newFolder.mkdir();
                    copyFolder(srcFile,newFolder);
                }
                //如果是文件
            }else {
                String srcFileName = srcFile.getName();
                File desFile = new File(desFolder, srcFileName);
                copyFile(srcFile,desFile);
            }

        }
    }

    //复制文件
    public static void copyFile (File srcFile, File desFile) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(srcFile),"utf-8"));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(desFile),"utf-8"));

        String temp = null;
        while((temp = br.readLine())!=null){
            bw.write(temp + "\n");
            bw.flush();
        }
        br.close();
        bw.close();
    }

    public static void deleteFile(File file) {
        //判断文件不为null或文件目录存在
        if (file == null || !file.exists()){
            return;
        }
        //取得这个目录下的所有子文件对象
        File[] files = file.listFiles();
        //遍历该目录下的文件对象
        for (File f: files){
            //打印文件名
            String name = file.getName();
            //判断子目录是否存在子目录,如果是文件则删除
            if (f.isDirectory()){
                deleteFile(f);
            }else {
                f.delete();
            }
        }
        //删除空文件夹  for循环已经把上一层节点的目录清空。
        file.delete();
    }

    public static void refreshWorkspace(String path, String projectFileName) {
        try {
            File f = new File(path + "\\" + projectFileName + "-workspace");
            deleteFile(f);// 删除该目录下所有文件夹和文件
            f = new File(path + "\\" + projectFileName + "-workspace");
            f.mkdir();// 重新创建目录
            File desFolder = new File(path + "\\" + projectFileName + "-workspace" + "\\" + projectFileName);
            File srcFolder = new File(path + "\\" + projectFileName);
            if(desFolder.mkdir()) {
                copyFolder(srcFolder, desFolder);
            } else {
                System.out.println("Error");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

2,复制后的区别如下: 

因此无法正常进行下一步的工作。

 

二,解决方法

从上面的截图可以看出,使用Java复制文件虽然可行,但是会改变某些隐藏文件的属性格式,导致原有命令执行失败(暂时没找到通过Java字节流复制文件的解决方法)

因此想通过执行cmd命令完成文件夹的复制工作(Windows中用cmd,Linux可进行相应的修改)。参考文章@dream_uping【cmd命令 复制文件夹里所有文件到另一个文件夹操作方式】

xcopy 源文件夹 目的文件夹 参数

xcopy D:\TestProjects\untitled D:\TestProjects\untitled-workspace /s /f /h

XCOPY是COPY的扩展,可以把指定的目录连文件和目录结构一并拷贝,但不能拷贝系统文件;

  • /S 复制目录和子目录,除了空的。
  • /F 复制时显示完整的源和目标文件名。
  • /H 也复制隐藏和系统文件。

1,相关代码如下:

GitUtil

import java.io.*;

public class GitUtil {

    public static void copyFolderByCMD(String scrFolder, String desFolder) {
        Runtime run = Runtime.getRuntime();
        try {
            Process process = run.exec("cmd.exe /c " + "xcopy " + scrFolder + " " + desFolder + " /s /f /h");

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public static void deleteFile(File file) {
        //判断文件不为null或文件目录存在
        if (file == null || !file.exists()){
            return;
        }
        //取得这个目录下的所有子文件对象
        File[] files = file.listFiles();
        //遍历该目录下的文件对象
        for (File f: files){
            //打印文件名
            String name = file.getName();
            //判断子目录是否存在子目录,如果是文件则删除
            if (f.isDirectory()){
                deleteFile(f);
            }else {
                f.delete();
            }
        }
        //删除空文件夹  for循环已经把上一层节点的目录清空。
        file.delete();
    }

    public static void refreshWorkspaceByCMD(String path, String projectFileName) {
        try {
            File f = new File(path + "\\" + projectFileName + "-workspace");
            deleteFile(f);// 删除该目录下所有文件夹和文件
            f = new File(path + "\\" + projectFileName + "-workspace");
            // 在项目所在目录下创建"项目名-workspace"文件夹
            f.mkdir();
            f = new File(path + "\\" + projectFileName + "-workspace" + "\\" + projectFileName);
            // 在"项目名-workspace"文件夹中创建与项目同名的文件夹
            if(f.mkdir()) {
                String srcFolder = path + "\\" + projectFileName;
                String desFolder = path + "\\" + projectFileName + "-workspace" + "\\" + projectFileName;
                copyFolderByCMD(srcFolder, desFolder);
            } else {
                System.out.println("Error");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

Main

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URLEncoder;
import java.util.*;

public class Main {

    public static void main(String[] args) {
        String path = "D:\\TestProjects";
        String projectFileName = "untitled";

        GitUtil.refreshWorkspaceByCMD(path, projectFileName);
    }
}

2,运行效果如下:

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值