<commit_before>package uk.ac.cam.cl.dtg.segue.git;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.Validate;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.NoHeadException;
import org.eclipse.jgit.errors.RevisionSyntaxException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectLoader;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.transport.FetchResult;
import org.eclipse.jgit.transport.JschConfigSessionFactory;
import org.eclipse.jgit.transport.OpenSshConfig;
import org.eclipse.jgit.transport.OpenSshConfig.Host;
import org.eclipse.jgit.transport.RefSpec;
import org.eclipse.jgit.transport.SshSessionFactory;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.treewalk.filter.PathFilter;
import org.eclipse.jgit.treewalk.filter.PathSuffixFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.inject.Inject;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;

/**
 * This class is a representation of the Git Database and provides some helper
 * methods to allow file access.
 *
 * It is responsible for providing basic functionality to search a specified Git
 * Repository and find files based on a given SHA.
 *
 */
public class GitDb
{
    private static final Logger log = LoggerFactory.getLogger(GitDb.class);

    private final String privateKey;
    private final String sshFetchUrl;

    private Git gitHandle;

    /**
     * Create a new instance of a GitDb object
     *
     * This will immediately try and connect to the Git folder specified to
     * check its validity.
     *
     * @param repoLocation
     *            - location of the local git repository
     * @throws IOException
     */
    public GitDb(String repoLocation) throws IOException {
        Validate.notBlank(repoLocation);

        // unused for this constructor
        this.privateKey = null;
        this.sshFetchUrl = null;

        gitHandle = Git.open(new File(repoLocation));
    }

    /**
     * Create a new instance of a GitDb object
     *
     * This will immediately try and connect to the Git folder specified to
     * check its validity.
     *
     * This constructor is only necessary if we want to access a private
     * repository.
     *
     * @param repoLocation
     *            - location of the local git repository
     * @param sshFetchUrl
     *            - location of the remote git repository (ssh url used for
     *            fetching only)
     * @param privateKeyFileLocation
     *            - location of the local private key file used to access the
     *            ssh FetchUrl
     * @throws IOException
     */
    @Inject
    public GitDb(String repoLocation, String sshFetchUrl,
            String privateKeyFileLocation) throws IOException {
        Validate.notBlank(repoLocation);

        this.sshFetchUrl = sshFetchUrl;
        this.privateKey = privateKeyFileLocation;

        gitHandle = Git.open(new File(repoLocation));
    }

    /**
     * Clone a repository and create a GitDb object.
     * <p>
     * Note, you may wish to delete the directory after you have finished with it.
     * This is entirely your responsibility!
     *
     * @param src Source repository path
     * @param dest Destination directory
     * @param bare Clone bare?
     * @param branch Branch to clone
     */
    public GitDb(String src, File dest, boolean bare, String branch, String remote, final String privateKey) throws IOException
    {
        this.privateKey = privateKey;
        this.sshFetchUrl = src;

		try {
			SshSessionFactory factory = new JschConfigSessionFactory() {
				@Override
				public void configure(Host hc, com.jcraft.jsch.Session session) {
                    // FIXME: Possibly consider manually adding SSH key,
                    // to avoid MITM attacks
                    session.setConfig("StrictHostKeyChecking", "no");
				}

                @Override
                protected JSch getJSch(final OpenSshConfig.Host hc,
                        org.eclipse.jgit.util.FS fs) throws JSchException {
                    JSch jsch = super.getJSch(hc, fs);
                    jsch.removeAllIdentity();

                    if (null != privateKey) {
                        jsch.addIdentity(privateKey);
                    }

                    return jsch;
                }
            };

            if (src != null)
                SshSessionFactory.setInstance(factory);

            log.info("Cloning " + src + " to " + dest);
            this.gitHandle =  Git.cloneRepository()<commit_msg>switched to using a TransportConfigCallback rather than changing the global SshSessionFactory singleton<commit_after>package uk.ac.cam.cl.dtg.segue.git;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.Validate;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.TransportConfigCallback;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.NoHeadException;
import org.eclipse.jgit.errors.RevisionSyntaxException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectLoader;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.transport.FetchResult;
import org.eclipse.jgit.transport.JschConfigSessionFactory;
import org.eclipse.jgit.transport.OpenSshConfig;
import org.eclipse.jgit.transport.OpenSshConfig.Host;
import org.eclipse.jgit.transport.RefSpec;
import org.eclipse.jgit.transport.SshSessionFactory;
import org.eclipse.jgit.transport.SshTransport;
import org.eclipse.jgit.transport.Transport;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.treewalk.filter.PathFilter;
import org.eclipse.jgit.treewalk.filter.PathSuffixFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.inject.Inject;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;

/**
 * This class is a representation of the Git Database and provides some helper
 * methods to allow file access.
 *
 * It is responsible for providing basic functionality to search a specified Git
 * Repository and find files based on a given SHA.
 *
 */
public class GitDb
{
    private static final Logger log = LoggerFactory.getLogger(GitDb.class);

    private final String privateKey;
    private final String sshFetchUrl;

    private Git gitHandle;

    /**
     * Create a new instance of a GitDb object
     *
     * This will immediately try and connect to the Git folder specified to
     * check its validity.
     *
     * @param repoLocation
     *            - location of the local git repository
     * @throws IOException
     */
    public GitDb(String repoLocation) throws IOException {
        Validate.notBlank(repoLocation);

        // unused for this constructor
        this.privateKey = null;
        this.sshFetchUrl = null;

        gitHandle = Git.open(new File(repoLocation));
    }

    /**
     * Create a new instance of a GitDb object
     *
     * This will immediately try and connect to the Git folder specified to
     * check its validity.
     *
     * This constructor is only necessary if we want to access a private
     * repository.
     *
     * @param repoLocation
     *            - location of the local git repository
     * @param sshFetchUrl
     *            - location of the remote git repository (ssh url used for
     *            fetching only)
     * @param privateKeyFileLocation
     *            - location of the local private key file used to access the
     *            ssh FetchUrl
     * @throws IOException
     */
    @Inject
    public GitDb(String repoLocation, String sshFetchUrl,
            String privateKeyFileLocation) throws IOException {
        Validate.notBlank(repoLocation);

        this.sshFetchUrl = sshFetchUrl;
        this.privateKey = privateKeyFileLocation;

        gitHandle = Git.open(new File(repoLocation));
    }

    /**
     * Clone a repository and create a GitDb object.
     * <p>
     * Note, you may wish to delete the directory after you have finished with it.
     * This is entirely your responsibility!
     *
     * @param src Source repository path
     * @param dest Destination directory
     * @param bare Clone bare?
     * @param branch Branch to clone
     */
    public GitDb(String src, File dest, boolean bare, String branch, String remote, final String privateKey) throws IOException
    {
        this.privateKey = privateKey;
        this.sshFetchUrl = src;

        final SshSessionFactory factory = new JschConfigSessionFactory() {
			@Override
			public void configure(Host hc, com.jcraft.jsch.Session session) {
                // FIXME: Possibly consider manually adding SSH key,
                // to avoid MITM attacks
                session.setConfig("StrictHostKeyChecking", "no");
			}

            @Override
            protected JSch getJSch(final OpenSshConfig.Host hc,
                    org.eclipse.jgit.util.FS fs) throws JSchException {
                JSch jsch = super.getJSch(hc, fs);
                jsch.removeAllIdentity();

                if (null != privateKey) {
                    jsch.addIdentity(privateKey);
                }

                return jsch;
            }
        };
        
        TransportConfigCallback setKeyCallback = new TransportConfigCallback() {
			@Override
			public void configure(Transport transport) {
				if (transport instanceof SshTransport) {
					SshTransport sshTransport = (SshTransport)transport;
					sshTransport.setSshSessionFactory(factory);
				}
			}
		};
        
		try {
            log.info("Cloning " + src + " to " + dest);
            this.gitHandle =  Git.cloneRepository()
            	.setTransportConfigCallback(setKeyCallback)
{'fraction_non_alphanumeric': 0.08027434312210201, 'fraction_numerical': 0.000579598145285935, 'mean_word_length': 2.6010434782608693, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3396066', 'n_tokens_mistral': 2913, 'n_tokens_neox': 2799, 'n_words': 807}