mirror of
				https://github.com/actions/checkout.git
				synced 2025-11-04 05:19:14 +08:00 
			
		
		
		
	Fetch all history for all tags and branches when fetch-depth=0 (#258)
This commit is contained in:
		
							
								
								
									
										135
									
								
								dist/index.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										135
									
								
								dist/index.js
									
									
									
									
										vendored
									
									
								
							@@ -3383,6 +3383,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
 | 
			
		||||
const url_1 = __webpack_require__(835);
 | 
			
		||||
const core = __importStar(__webpack_require__(470));
 | 
			
		||||
const github = __importStar(__webpack_require__(469));
 | 
			
		||||
exports.tagsRefSpec = '+refs/tags/*:refs/tags/*';
 | 
			
		||||
function getCheckoutInfo(git, ref, commit) {
 | 
			
		||||
    return __awaiter(this, void 0, void 0, function* () {
 | 
			
		||||
        if (!git) {
 | 
			
		||||
@@ -3429,6 +3430,15 @@ function getCheckoutInfo(git, ref, commit) {
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
exports.getCheckoutInfo = getCheckoutInfo;
 | 
			
		||||
function getRefSpecForAllHistory(ref, commit) {
 | 
			
		||||
    const result = ['+refs/heads/*:refs/remotes/origin/*', exports.tagsRefSpec];
 | 
			
		||||
    if (ref && ref.toUpperCase().startsWith('REFS/PULL/')) {
 | 
			
		||||
        const branch = ref.substring('refs/pull/'.length);
 | 
			
		||||
        result.push(`+${commit || ref}:refs/remotes/pull/${branch}`);
 | 
			
		||||
    }
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
exports.getRefSpecForAllHistory = getRefSpecForAllHistory;
 | 
			
		||||
function getRefSpec(ref, commit) {
 | 
			
		||||
    if (!ref && !commit) {
 | 
			
		||||
        throw new Error('Args ref and commit cannot both be empty');
 | 
			
		||||
@@ -3478,6 +3488,50 @@ function getRefSpec(ref, commit) {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
exports.getRefSpec = getRefSpec;
 | 
			
		||||
/**
 | 
			
		||||
 * Tests whether the initial fetch created the ref at the expected commit
 | 
			
		||||
 */
 | 
			
		||||
function testRef(git, ref, commit) {
 | 
			
		||||
    return __awaiter(this, void 0, void 0, function* () {
 | 
			
		||||
        if (!git) {
 | 
			
		||||
            throw new Error('Arg git cannot be empty');
 | 
			
		||||
        }
 | 
			
		||||
        if (!ref && !commit) {
 | 
			
		||||
            throw new Error('Args ref and commit cannot both be empty');
 | 
			
		||||
        }
 | 
			
		||||
        // No SHA? Nothing to test
 | 
			
		||||
        if (!commit) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        // SHA only?
 | 
			
		||||
        else if (!ref) {
 | 
			
		||||
            return yield git.shaExists(commit);
 | 
			
		||||
        }
 | 
			
		||||
        const upperRef = ref.toUpperCase();
 | 
			
		||||
        // refs/heads/
 | 
			
		||||
        if (upperRef.startsWith('REFS/HEADS/')) {
 | 
			
		||||
            const branch = ref.substring('refs/heads/'.length);
 | 
			
		||||
            return ((yield git.branchExists(true, `origin/${branch}`)) &&
 | 
			
		||||
                commit === (yield git.revParse(`refs/remotes/origin/${branch}`)));
 | 
			
		||||
        }
 | 
			
		||||
        // refs/pull/
 | 
			
		||||
        else if (upperRef.startsWith('REFS/PULL/')) {
 | 
			
		||||
            // Assume matches because fetched using the commit
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        // refs/tags/
 | 
			
		||||
        else if (upperRef.startsWith('REFS/TAGS/')) {
 | 
			
		||||
            const tagName = ref.substring('refs/tags/'.length);
 | 
			
		||||
            return ((yield git.tagExists(tagName)) && commit === (yield git.revParse(ref)));
 | 
			
		||||
        }
 | 
			
		||||
        // Unexpected
 | 
			
		||||
        else {
 | 
			
		||||
            core.debug(`Unexpected ref format '${ref}' when testing ref info`);
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
exports.testRef = testRef;
 | 
			
		||||
function checkCommitInfo(token, commitInfo, repositoryOwner, repositoryName, ref, commit) {
 | 
			
		||||
    return __awaiter(this, void 0, void 0, function* () {
 | 
			
		||||
        try {
 | 
			
		||||
@@ -5634,6 +5688,7 @@ const exec = __importStar(__webpack_require__(986));
 | 
			
		||||
const fshelper = __importStar(__webpack_require__(618));
 | 
			
		||||
const io = __importStar(__webpack_require__(1));
 | 
			
		||||
const path = __importStar(__webpack_require__(622));
 | 
			
		||||
const refHelper = __importStar(__webpack_require__(227));
 | 
			
		||||
const regexpHelper = __importStar(__webpack_require__(528));
 | 
			
		||||
const retryHelper = __importStar(__webpack_require__(587));
 | 
			
		||||
const git_version_1 = __webpack_require__(559);
 | 
			
		||||
@@ -5749,18 +5804,14 @@ class GitCommandManager {
 | 
			
		||||
            return output.exitCode === 0;
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
    fetch(fetchDepth, refSpec) {
 | 
			
		||||
    fetch(refSpec, fetchDepth) {
 | 
			
		||||
        return __awaiter(this, void 0, void 0, function* () {
 | 
			
		||||
            const args = [
 | 
			
		||||
                '-c',
 | 
			
		||||
                'protocol.version=2',
 | 
			
		||||
                'fetch',
 | 
			
		||||
                '--no-tags',
 | 
			
		||||
                '--prune',
 | 
			
		||||
                '--progress',
 | 
			
		||||
                '--no-recurse-submodules'
 | 
			
		||||
            ];
 | 
			
		||||
            if (fetchDepth > 0) {
 | 
			
		||||
            const args = ['-c', 'protocol.version=2', 'fetch'];
 | 
			
		||||
            if (!refSpec.some(x => x === refHelper.tagsRefSpec)) {
 | 
			
		||||
                args.push('--no-tags');
 | 
			
		||||
            }
 | 
			
		||||
            args.push('--prune', '--progress', '--no-recurse-submodules');
 | 
			
		||||
            if (fetchDepth && fetchDepth > 0) {
 | 
			
		||||
                args.push(`--depth=${fetchDepth}`);
 | 
			
		||||
            }
 | 
			
		||||
            else if (fshelper.fileExistsSync(path.join(this.workingDirectory, '.git', 'shallow'))) {
 | 
			
		||||
@@ -5819,9 +5870,28 @@ class GitCommandManager {
 | 
			
		||||
    removeEnvironmentVariable(name) {
 | 
			
		||||
        delete this.gitEnv[name];
 | 
			
		||||
    }
 | 
			
		||||
    /**
 | 
			
		||||
     * Resolves a ref to a SHA. For a branch or lightweight tag, the commit SHA is returned.
 | 
			
		||||
     * For an annotated tag, the tag SHA is returned.
 | 
			
		||||
     * @param {string} ref  For example: 'refs/heads/master' or '/refs/tags/v1'
 | 
			
		||||
     * @returns {Promise<string>}
 | 
			
		||||
     */
 | 
			
		||||
    revParse(ref) {
 | 
			
		||||
        return __awaiter(this, void 0, void 0, function* () {
 | 
			
		||||
            const output = yield this.execGit(['rev-parse', ref]);
 | 
			
		||||
            return output.stdout.trim();
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
    setEnvironmentVariable(name, value) {
 | 
			
		||||
        this.gitEnv[name] = value;
 | 
			
		||||
    }
 | 
			
		||||
    shaExists(sha) {
 | 
			
		||||
        return __awaiter(this, void 0, void 0, function* () {
 | 
			
		||||
            const args = ['rev-parse', '--verify', '--quiet', `${sha}^{object}`];
 | 
			
		||||
            const output = yield this.execGit(args, true);
 | 
			
		||||
            return output.exitCode === 0;
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
    submoduleForeach(command, recursive) {
 | 
			
		||||
        return __awaiter(this, void 0, void 0, function* () {
 | 
			
		||||
            const args = ['submodule', 'foreach'];
 | 
			
		||||
@@ -6060,7 +6130,7 @@ function getSource(settings) {
 | 
			
		||||
        core.endGroup();
 | 
			
		||||
        // Prepare existing directory, otherwise recreate
 | 
			
		||||
        if (isExisting) {
 | 
			
		||||
            yield gitDirectoryHelper.prepareExistingDirectory(git, settings.repositoryPath, repositoryUrl, settings.clean);
 | 
			
		||||
            yield gitDirectoryHelper.prepareExistingDirectory(git, settings.repositoryPath, repositoryUrl, settings.clean, settings.ref);
 | 
			
		||||
        }
 | 
			
		||||
        if (!git) {
 | 
			
		||||
            // Downloading using REST API
 | 
			
		||||
@@ -6102,8 +6172,21 @@ function getSource(settings) {
 | 
			
		||||
            }
 | 
			
		||||
            // Fetch
 | 
			
		||||
            core.startGroup('Fetching the repository');
 | 
			
		||||
            const refSpec = refHelper.getRefSpec(settings.ref, settings.commit);
 | 
			
		||||
            yield git.fetch(settings.fetchDepth, refSpec);
 | 
			
		||||
            if (settings.fetchDepth <= 0) {
 | 
			
		||||
                // Fetch all branches and tags
 | 
			
		||||
                let refSpec = refHelper.getRefSpecForAllHistory(settings.ref, settings.commit);
 | 
			
		||||
                yield git.fetch(refSpec);
 | 
			
		||||
                // When all history is fetched, the ref we're interested in may have moved to a different
 | 
			
		||||
                // commit (push or force push). If so, fetch again with a targeted refspec.
 | 
			
		||||
                if (!(yield refHelper.testRef(git, settings.ref, settings.commit))) {
 | 
			
		||||
                    refSpec = refHelper.getRefSpec(settings.ref, settings.commit);
 | 
			
		||||
                    yield git.fetch(refSpec);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                const refSpec = refHelper.getRefSpec(settings.ref, settings.commit);
 | 
			
		||||
                yield git.fetch(refSpec, settings.fetchDepth);
 | 
			
		||||
            }
 | 
			
		||||
            core.endGroup();
 | 
			
		||||
            // Checkout info
 | 
			
		||||
            core.startGroup('Determining the checkout info');
 | 
			
		||||
@@ -7454,7 +7537,7 @@ const fs = __importStar(__webpack_require__(747));
 | 
			
		||||
const fsHelper = __importStar(__webpack_require__(618));
 | 
			
		||||
const io = __importStar(__webpack_require__(1));
 | 
			
		||||
const path = __importStar(__webpack_require__(622));
 | 
			
		||||
function prepareExistingDirectory(git, repositoryPath, repositoryUrl, clean) {
 | 
			
		||||
function prepareExistingDirectory(git, repositoryPath, repositoryUrl, clean, ref) {
 | 
			
		||||
    return __awaiter(this, void 0, void 0, function* () {
 | 
			
		||||
        assert.ok(repositoryPath, 'Expected repositoryPath to be defined');
 | 
			
		||||
        assert.ok(repositoryUrl, 'Expected repositoryUrl to be defined');
 | 
			
		||||
@@ -7494,10 +7577,24 @@ function prepareExistingDirectory(git, repositoryPath, repositoryUrl, clean) {
 | 
			
		||||
                for (const branch of branches) {
 | 
			
		||||
                    yield git.branchDelete(false, branch);
 | 
			
		||||
                }
 | 
			
		||||
                // Remove all refs/remotes/origin/* to avoid conflicts
 | 
			
		||||
                branches = yield git.branchList(true);
 | 
			
		||||
                for (const branch of branches) {
 | 
			
		||||
                    yield git.branchDelete(true, branch);
 | 
			
		||||
                // Remove any conflicting refs/remotes/origin/*
 | 
			
		||||
                // Example 1: Consider ref is refs/heads/foo and previously fetched refs/remotes/origin/foo/bar
 | 
			
		||||
                // Example 2: Consider ref is refs/heads/foo/bar and previously fetched refs/remotes/origin/foo
 | 
			
		||||
                if (ref) {
 | 
			
		||||
                    ref = ref.startsWith('refs/') ? ref : `refs/heads/${ref}`;
 | 
			
		||||
                    if (ref.startsWith('refs/heads/')) {
 | 
			
		||||
                        const upperName1 = ref.toUpperCase().substr('REFS/HEADS/'.length);
 | 
			
		||||
                        const upperName1Slash = `${upperName1}/`;
 | 
			
		||||
                        branches = yield git.branchList(true);
 | 
			
		||||
                        for (const branch of branches) {
 | 
			
		||||
                            const upperName2 = branch.substr('origin/'.length).toUpperCase();
 | 
			
		||||
                            const upperName2Slash = `${upperName2}/`;
 | 
			
		||||
                            if (upperName1.startsWith(upperName2Slash) ||
 | 
			
		||||
                                upperName2.startsWith(upperName1Slash)) {
 | 
			
		||||
                                yield git.branchDelete(true, branch);
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                core.endGroup();
 | 
			
		||||
                // Clean
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user