绝了,一句话写完一个功能,用Bito初体验。

简介: 绝了,一句话写完一个功能,用Bito初体验。

大家好,使用ai写代码已经现在很火的技术,作为一名工程师,更应该与时俱进,今天演示一下通过Bito-chatgpt来完成一个功能,ai已经能完成大部分工作了,只需要小调整就可以。

接下来来看交互的过程。

任务问题:使用jgit统计每个工程师的代码提交的行数

Bito的回答

要使用 JGit 统计每个工程师代码提交的行数,可以按照以下步骤来实现:

1. 获取 Git 仓库:需要初始化 Git 对象,并设置 Git 仓库的路径。

FileRepositoryBuilder builder = new FileRepositoryBuilder();
   Repository repository = builder.setGitDir(new File("path/to/git/repo"))
           .readEnvironment() // scan environment GIT_* variables
           .findGitDir() // scan up the file system tree
           .build();
   Git git = new Git(repository);

2. 获取提交记录:使用 git.log().all().call() 方法获取仓库中所有的提交记录。

Iterable<RevCommit> commits = git.log().all().call();

3. 遍历提交记录,统计每个工程师的行数。

统计每个工程师的行数,可以通过解析提交记录中的作者信息来实现,例如:
Map<String, Integer> authorToLineCount = new HashMap<>();
   for (RevCommit commit : commits) {
   
   
       String authorName = commit.getAuthorIdent().getName();
       int linesAdded = 0;
       int linesDeleted = 0;
       TreeWalk treeWalk = new TreeWalk(repository);
       treeWalk.addTree(commit.getTree());
       if (commit.getParentCount() > 0) {
   
   
           treeWalk.addTree(commit.getParent(0).getTree());
       }
       treeWalk.setRecursive(true);
       while (treeWalk.next()) {
   
   
           if (treeWalk.isSubtree()) {
   
   
               treeWalk.enterSubtree();
               continue;
           }
           FileMode fileMode = treeWalk.getFileMode(0);
           if (fileMode == FileMode.REGULAR_FILE) {
   
   
               ObjectId objectId = treeWalk.getObjectId(0);
               ObjectLoader loader = repository.open(objectId);
               ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
               loader.copyTo(outputStream);
               String content = new String(outputStream.toByteArray());
               linesAdded += countLinesAdded(content);
               linesDeleted += countLinesDeleted(content);
           }
       }
       int lineCount = linesAdded - linesDeleted;
       if (authorToLineCount.containsKey(authorName)) {
   
   
           lineCount += authorToLineCount.get(authorName);
       }
       authorToLineCount.put(authorName, lineCount);
   }

在上面的代码中,首先遍历提交记录中的每个提交,然后获取提交作者的姓名,并初始化一个 Map 对象来存储每个作者的代码行数。接下来,遍历提交记录中的每个文件,计算该文件中新增和删除的代码行数,并将其累加到作者的代码行数中。最后,输出每个作者的代码行数。

统计新增和删除的代码行数,可以编写一个简单的帮助函数。例如,以下函数可以计算文件中新增的代码行数:
private static int countLinesAdded(String content) {
   
   
       int count = 0;
       Scanner scanner = new Scanner(content);
       while (scanner.hasNextLine()) {
   
   
           String line = scanner.nextLine();
           if (line.startsWith("+")) {
   
   
               count++;
           }
       }
       scanner.close();
       return count;
   }

同理,以下函数可以计算文件中删除的代码行数:

private static int countLinesDeleted(String content) {
   
   
       int count = 0;
       Scanner scanner = new Scanner(content);
       while (scanner.hasNextLine()) {
   
   
           String line = scanner.nextLine();
           if (line.startsWith("-")) {
   
   
               count++;
           }
       }
       scanner.close();
       return count;
   }

完整的代码示例如下:

import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.lib.*;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.treewalk.TreeWalk;
 import java.io.ByteArrayOutputStream;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
 public class CommitStats {
   
   
    public static void main(String[] args) throws Exception {
   
   
        FileRepositoryBuilder builder = new FileRepositoryBuilder();
        Repository repository = builder.setGitDir(new File("path/to/git/repo"))
                .readEnvironment() // scan environment GIT_* variables
                .findGitDir() // scan up the file system tree
                .build();
        try (Git git = new Git(repository)) {
   
   
            Iterable<RevCommit> commits = git.log().all().call();
            Map<String, Integer> authorToLineCount = new HashMap<>();
            for (RevCommit commit : commits) {
   
   
                String authorName = commit.getAuthorIdent().getName();
                int linesAdded = 0;
                int linesDeleted = 0;
                TreeWalk treeWalk = new TreeWalk(repository);
                treeWalk.addTree(commit.getTree());
                if (commit.getParentCount() > 0) {
   
   
                    treeWalk.addTree(commit.getParent(0).getTree());
                }
                treeWalk.setRecursive(true);
                while (treeWalk.next()) {
   
   
                    if (treeWalk.isSubtree()) {
   
   
                        treeWalk.enterSubtree();
                        continue;
                    }
                    FileMode fileMode = treeWalk.getFileMode(0);
                    if (fileMode == FileMode.REGULAR_FILE) {
   
   
                        ObjectId objectId = treeWalk.getObjectId(0);
                        ObjectLoader loader = repository.open(objectId);
                        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                        loader.copyTo(outputStream);
                        String content = new String(outputStream.toByteArray());
                        linesAdded += countLinesAdded(content);
                        linesDeleted += countLinesDeleted(content);
                    }
                }
                int lineCount = linesAdded - linesDeleted;
                if (authorToLineCount.containsKey(authorName)) {
   
   
                    lineCount += authorToLineCount.get(authorName);
                }
                authorToLineCount.put(authorName, lineCount);
            }
            for (Map.Entry<String, Integer> entry : authorToLineCount.entrySet()) {
   
   
                System.out.println(entry.getKey() + ": " + entry.getValue());
            }
        }
    }
     private static int countLinesAdded(String content) {
   
   
        int count = 0;
        Scanner scanner = new Scanner(content);
        while (scanner.hasNextLine()) {
   
   
            String line = scanner.nextLine();
            if (line.startsWith("+")) {
   
   
                count++;
            }
        }
        scanner.close();
        return count;
    }
     private static int countLinesDeleted(String content) {
   
   
        int count = 0;
        Scanner scanner = new Scanner(content);
        while (scanner.hasNextLine()) {
   
   
            String line = scanner.nextLine();
            if (line.startsWith("-")) {
   
   
                count++;
            }
        }
        scanner.close();
        return count;
    }
}

在这个示例代码中,我们假设提交者的姓名唯一标识每个工程师,并且使用姓名作为 key 存储每个工程师提交的代码量。

把代码拷到程序文件中,运行,报错了,如下:

Exception in thread "main" org.eclipse.jgit.api.errors.NoHeadException: No HEAD exists and no explicit starting revision was specified

继续请教Bito:

AI: This error message indicates that the Git repository in question does not have a valid HEAD reference, and no starting revision was specified for the operation being performed. To resolve this issue, you may need to create a new branch or reset the repository to a known good state. It is also possible that there is a problem with the Git client or server configuration. Please refer to the Git documentation or seek assistance from a Git expert for further guidance.

那么这个git的GitDir要如何传入呢?

继续问:FileRepositoryBuilder.setGitDir 如何设置?

AI: FileRepositoryBuilder.setGitDir is a method used to set the directory of the git repository. You can use it to specify the path to the .git directory of the repository that you want to access on your local machine. Here's an example of how to use it:

File gitDir = new File("/path/to/your/git/repository/.git");
FileRepositoryBuilder builder = new FileRepositoryBuilder();
Repository repo = builder
    .setGitDir(gitDir)
    .readEnvironment()
    .findGitDir()
    .build();

In this example, we create a File object pointing to the .git directory of the repository, and then use the setGitDir method to set it as the directory for the FileRepositoryBuilder . This sets up the builder with the repository configuration, and we can then use it to create a Repository object that represents access to the repository.

通过提示,需要配置到指定的目录下的.git目录才行。

修改读取的gitdir目录,运行成功。

调整后的代码如下:

public static void main(String[] args) throws Exception {
   
   
    FileRepositoryBuilder builder = new FileRepositoryBuilder();
    Repository repository = builder.setGitDir(new File("/xxx/xx/xx/.git"))
            .readEnvironment() // scan environment GIT_* variables
            .findGitDir() // scan up the file system tree
            .build();
    try (Git git = new Git(repository)) {
   
   
        Iterable<RevCommit> commits = git.log().all().call();
        Map<String, Map<String, Integer>> authorToLineCount = new HashMap<>();
        for (RevCommit commit : commits) {
   
   
            String authorName = commit.getAuthorIdent().getName();
            int linesAdded = 0;
            int linesDeleted = 0;
            TreeWalk treeWalk = new TreeWalk(repository);
            treeWalk.addTree(commit.getTree());
            if (commit.getParentCount() > 0) {
   
   
                treeWalk.addTree(commit.getParent(0).getTree());
            }
            treeWalk.setRecursive(true);
            while (treeWalk.next()) {
   
   
                if (treeWalk.isSubtree()) {
   
   
                    treeWalk.enterSubtree();
                    continue;
                }
                FileMode fileMode = treeWalk.getFileMode(0);
                if (fileMode == FileMode.REGULAR_FILE) {
   
   
                    ObjectId objectId = treeWalk.getObjectId(0);
                    ObjectLoader loader = repository.open(objectId);
                    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                    loader.copyTo(outputStream);
                    String content = new String(outputStream.toByteArray());
                    linesAdded += countLinesAdded(content);
                    linesDeleted += countLinesDeleted(content);
                }
            }
            //int lineCount = linesAdded - linesDeleted;

            if (authorToLineCount.containsKey(authorName)) {
   
   
                linesAdded += authorToLineCount.get(authorName).get("ADD");
                linesDeleted += authorToLineCount.get(authorName).get("DEL");
            }
            Map<String, Integer> lines = new HashMap<>();
            lines.put("ADD", linesAdded);
            lines.put("DEL", linesDeleted);
            authorToLineCount.put(authorName, lines);

        }
        for (Map.Entry<String, Map<String, Integer>> entry : authorToLineCount.entrySet()) {
   
   
            System.out.println(entry.getKey() + "添加: " + entry.getValue().get("ADD") + ",删除:" + entry.getValue().get("DEL"));
        }
    }
}

private static int countLinesAdded(String content) {
   
   
    int count = 0;
    Scanner scanner = new Scanner(content);
    while (scanner.hasNextLine()) {
   
   
        String line = scanner.nextLine();
        if (!Objects.equals(line, "") && !line.startsWith("-")) {
   
   
            count++;
        }
    }
    scanner.close();
    return count;
}

private static int countLinesDeleted(String content) {
   
   
    int count = 0;
    Scanner scanner = new Scanner(content);
    while (scanner.hasNextLine()) {
   
   
        String line = scanner.nextLine();
        if (line.startsWith("-")) {
   
   
            count++;
        }
    }
    scanner.close();
    return count;
}

统计了一个线上项目的情况如下:

image.png

ai提示写代码已经很不错了,要学习并去使用它,让它为你而做。接下来会写利用Bito来开发一个简单的系统,只要你略微懂点技术就可以。

目录
相关文章
|
4月前
|
开发工具 Android开发 iOS开发
从零开始学 Xamarin 开发,新手教程全攻略,安装环境、创建项目、设计界面,轻松开启开发之旅!
【8月更文挑战第31天】Xamarin是一种高效的跨平台移动应用开发工具,迎合了日益增长的移动应用需求。本文为Xamarin新手提供了一套详尽的入门指南,涵盖开发环境搭建、项目创建与配置、用户界面设计及功能实现等关键步骤。通过具体示例,帮助初学者快速上手Xamarin开发,开启移动应用创作之旅。
59 0
|
iOS开发
CTMediator 的初体验
​ 现在对于iOS开发的要求随着时代的发展,也在渐渐地演变。这几天看到了很多JD的要求,多多少少都会提到这样的一个名字-组件化。
|
存储 网络安全 文件存储
UNRAID系统初体验
UNRAID系统初体验
566 0
UNRAID系统初体验
|
存储 弹性计算 Java
我的阿里云初体验
经过同学的推荐,参加了阿里云的“飞天加速计划·高校学生在家实践 ”,首次体验了阿里云的ECS服务器,整体来说使用体验非常好,也非常推荐大家来使用ECS服务器。
205 0
我的阿里云初体验
|
Kubernetes 图形学 容器
【Agones系列】Agones初体验
本文介绍了Agones并在阿里云容器服务上运行Agones进行游戏服部署
【Agones系列】Agones初体验
|
机器学习/深度学习 弹性计算 算法
阿里云初体验
正式开启学习编程,希望能通过阿里云学到本领。从教学例程来看整体的使用过程是非常简单友好的。阿里云的控制台的使用体验是非常不错的,界面的信息都比较简单易懂。感谢阿里云提供这样的资源。
135 0
|
Java Linux Docker
阿里云的使用初体验
学生党在面对虚拟机的时候首先还是推荐使用阿里云的虚拟机,原因让我娓娓道来;
|
存储 弹性计算 Linux
阿里云初体验心得
我是一名就读于计算机科学与技术专业的在校生,学习期间在老师那了解到了“飞天加速计划”,通过简单的答题之后,我领取到了一台ECS云服务器,并计划将其作为之后自学相应网站开发的基础。
|
Linux 数据安全/隐私保护
使用阿里云的初体验
使用阿里云的初体验
|
域名解析 JavaScript Java