From 528c53bba0a5078c35b39f2c6292a48d22f09d92 Mon Sep 17 00:00:00 2001 From: Twarit Waikar Date: Wed, 18 Feb 2026 16:07:14 +0530 Subject: [PATCH 1/2] Revert "feat(p4_api): support older perforce servers" This reverts commit f7e205b190b15cc3eb49f23e0c7d87250433910f. There is a difference between the following 2 commands - 1. ``` p4 changes -s "submitted" -r -m 2 '//...@>CL_NUMBER' # Counts from CL_NUMBER ``` 2. ``` p4 changes -s "submitted" -m 2 '//...@>CL_NUMBER' # Count from the latest change ``` --- p4-fusion/commands/changes_result.cc | 6 --- p4-fusion/commands/changes_result.h | 3 +- p4-fusion/p4_api.cc | 72 ++++++++++++++-------------- 3 files changed, 38 insertions(+), 43 deletions(-) diff --git a/p4-fusion/commands/changes_result.cc b/p4-fusion/commands/changes_result.cc index b58a4063..6450518a 100644 --- a/p4-fusion/commands/changes_result.cc +++ b/p4-fusion/commands/changes_result.cc @@ -4,7 +4,6 @@ * SPDX-License-Identifier: BSD-3-Clause * For full license text, see the LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ -#include #include "changes_result.h" void ChangesResult::OutputStat(StrDict* varList) @@ -15,8 +14,3 @@ void ChangesResult::OutputStat(StrDict* varList) varList->GetVar("user")->Text(), varList->GetVar("time")->Atoi64()); } - -void ChangesResult::reverse() -{ - std::reverse(m_Changes.begin(), m_Changes.end()); -} diff --git a/p4-fusion/commands/changes_result.h b/p4-fusion/commands/changes_result.h index 92b5f6e6..9159bf73 100644 --- a/p4-fusion/commands/changes_result.h +++ b/p4-fusion/commands/changes_result.h @@ -7,7 +7,9 @@ #pragma once #include + #include "common.h" + #include "change_list.h" #include "result.h" @@ -18,7 +20,6 @@ class ChangesResult : public Result public: std::vector& GetChanges() { return m_Changes; } - void reverse(); void OutputStat(StrDict* varList) override; }; diff --git a/p4-fusion/p4_api.cc b/p4-fusion/p4_api.cc index d86567a5..7a7fa0df 100644 --- a/p4-fusion/p4_api.cc +++ b/p4-fusion/p4_api.cc @@ -185,10 +185,10 @@ std::unique_ptr P4API::TestConnection(const int retries) std::unique_ptr P4API::ShortChanges(const std::string& path) { std::unique_ptr changes = Run("changes", { - "-s", "submitted", // Only include submitted CLs - path // Depot path to get CLs from - }); - changes->reverse(); + "-r", // Get CLs from earliest to latest + "-s", "submitted", // Only include submitted CLs + path // Depot path to get CLs from + }); return changes; } @@ -196,10 +196,10 @@ std::unique_ptr P4API::Changes(const std::string& path) { MTR_SCOPE("P4", __func__); return Run("changes", { - "-l", // Get full descriptions instead of sending cut-short ones - "-s", "submitted", // Only include submitted CLs - path // Depot path to get CLs from - }); + "-l", // Get full descriptions instead of sending cut-short ones + "-s", "submitted", // Only include submitted CLs + path // Depot path to get CLs from + }); } std::unique_ptr P4API::Changes(const std::string& path, const std::string& from, int32_t maxCount) @@ -207,6 +207,7 @@ std::unique_ptr P4API::Changes(const std::string& path, const std std::vector args = { "-l", // Get full descriptions instead of sending cut-short ones "-s", "submitted", // Only include submitted CLs + "-r" // Send CLs in chronological order }; // This needs to be declared outside the if scope below to @@ -233,7 +234,6 @@ std::unique_ptr P4API::Changes(const std::string& path, const std args.push_back(path + pathAddition); std::unique_ptr result = Run("changes", args); - result->reverse(); return result; } @@ -241,29 +241,29 @@ std::unique_ptr P4API::ChangesFromTo(const std::string& path, con { std::string pathArg = path + "@" + from + "," + to; return Run("changes", { - "-s", "submitted", // Only include submitted CLs - pathArg // Depot path to get CLs from - }); + "-s", "submitted", // Only include submitted CLs + pathArg // Depot path to get CLs from + }); } std::unique_ptr P4API::LatestChange(const std::string& path) { MTR_SCOPE("P4", __func__); return Run("changes", { - "-s", "submitted", // Only include submitted CLs, - "-m", "1", // Get top-most change - path // Depot path to get CLs from - }); + "-s", "submitted", // Only include submitted CLs, + "-m", "1", // Get top-most change + path // Depot path to get CLs from + }); } std::unique_ptr P4API::OldestChange(const std::string& path) { std::unique_ptr changes = Run("changes", { - "-s", "submitted", // Only include submitted CLs, - "-m", "1", // Get top-most change - path // Depot path to get CLs from - }); - changes->reverse(); + "-r", // List from earliest to latest + "-s", "submitted", // Only include submitted CLs, + "-m", "1", // Get top-most change + path // Depot path to get CLs from + }); return changes; } @@ -271,17 +271,17 @@ std::unique_ptr P4API::Describe(const std::string& cl) { MTR_SCOPE("P4", __func__); return Run("describe", { "-s", // Omit the diffs - cl }); + cl }); } std::unique_ptr P4API::FileLog(const std::string& changelist) { return Run("filelog", { - "-c", // restrict output to a single changelist - changelist, - "-m1", // don't get the full history, just the first entry. - "//..." // rather than require the path to be passed in, just list all files. - }); + "-c", // restrict output to a single changelist + changelist, + "-m1", // don't get the full history, just the first entry. + "//..." // rather than require the path to be passed in, just list all files. + }); } std::unique_ptr P4API::Size(const std::string& file) @@ -298,16 +298,16 @@ std::unique_ptr P4API::GetFilesToSyncAtCL(const std::string& path, c { std::string clCommand = "@" + cl; return Run("sync", { - "-n", // Only preview the files to sync. Don't send file contents...yet - clCommand, - }); + "-n", // Only preview the files to sync. Don't send file contents...yet + clCommand, + }); } std::unique_ptr P4API::PrintFile(const std::string& filePathRevision) { return Run("print", { - filePathRevision, - }); + filePathRevision, + }); } std::unique_ptr P4API::PrintFiles(const std::vector& fileRevisions) @@ -325,15 +325,15 @@ std::unique_ptr P4API::PrintFiles(const std::vector& f std::unique_ptr P4API::Sync(const std::string& path) { return Run("sync", { - path // Sync a particular depot path - }); + path // Sync a particular depot path + }); } std::unique_ptr P4API::Users() { return Run("users", { - "-a" // Include service accounts - }); + "-a" // Include service accounts + }); } std::unique_ptr P4API::Info() From 62212021d777d406e95dae6d105f5dd3eae396a3 Mon Sep 17 00:00:00 2001 From: Twarit Waikar Date: Wed, 18 Feb 2026 17:33:35 +0530 Subject: [PATCH 2/2] Minor fixes to the build process --- README.md | 3 +- generate_cache.sh | 4 +- p4-fusion/git_api.cc | 7 ++- p4-fusion/git_api.h | 108 +++++++++++++++++++++---------------------- p4-fusion/main.cc | 11 +++-- 5 files changed, 70 insertions(+), 63 deletions(-) diff --git a/README.md b/README.md index c4e18844..f154f1c3 100644 --- a/README.md +++ b/README.md @@ -138,7 +138,8 @@ Because of the extra effort the script performs, expect it to take orders of mag ## Build 0. Pre-requisites - * Install openssl (both 1.1.1 and 3 work) + * Install zlib - `brew install zlib` + * Install openssl (try 1.1.1, 3.x.x doesn't work with p4 API libs) - `brew install openssl@1.1` * Install CMake 3.16+. * Install g++ 11.2.0 (older versions compatible with C++11 are also supported). * Clone this repository or [get a release distribution](https://github.com/salesforce/p4-fusion/releases). diff --git a/generate_cache.sh b/generate_cache.sh index c9e10c38..b6580ec6 100755 --- a/generate_cache.sh +++ b/generate_cache.sh @@ -9,13 +9,13 @@ cmakeArgs=( -DBUILD_SHARED_LIBS=OFF -DBUILD_CLAR=OFF -DBUILD_EXAMPLES=OFF - -DUSE_BUNDLED_ZLIB=ON + -DUSE_BUNDLED_ZLIB=OFF -DREGEX_BACKEND=builtin -DTHREADSAFE=ON -DUSE_SSH=OFF -DUSE_HTTPS=OFF -DUSE_THREADS=ON - -DOPENSSL_ROOT_DIR=/usr/local/ssl + -DOPENSSL_ROOT_DIR=/opt/homebrew/Cellar/openssl@1.1/1.1.1w -DCMAKE_C_COMPILER=/usr/bin/gcc -DCMAKE_CXX_COMPILER=/usr/bin/g++ ) diff --git a/p4-fusion/git_api.cc b/p4-fusion/git_api.cc index 5d07119a..000e44d5 100644 --- a/p4-fusion/git_api.cc +++ b/p4-fusion/git_api.cc @@ -263,7 +263,7 @@ std::string GitAPI::Commit( const std::string& user, const std::string& email, const int& timezone, - const std::string& desc, + std::string desc, const int64_t& timestamp, const std::string& mergeFromStream) { @@ -278,6 +278,11 @@ std::string GitAPI::Commit( git_signature* author = nullptr; GIT2(git_signature_new(&author, user.c_str(), email.c_str(), timestamp, timezone)); + STDHelpers::StripSurrounding(desc, '\n'); + STDHelpers::StripSurrounding(desc, '\r'); + STDHelpers::StripSurrounding(desc, ' '); + STDHelpers::StripSurrounding(desc, '\t'); + // -3 to remove the trailing "..." std::string commitMsg = cl + " - " + desc + "\n[p4-fusion: depot-paths = \"" + depotPath.substr(0, depotPath.size() - 3) + "\": change = " + cl + "]"; diff --git a/p4-fusion/git_api.h b/p4-fusion/git_api.h index 7c8874e0..64be02f0 100644 --- a/p4-fusion/git_api.h +++ b/p4-fusion/git_api.h @@ -1,54 +1,54 @@ -/* - * Copyright (c) 2022 Salesforce, Inc. - * All rights reserved. - * SPDX-License-Identifier: BSD-3-Clause - * For full license text, see the LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause - */ -#pragma once - -#include -#include -#include - -#include "common.h" -#include "git2/oid.h" - -struct git_repository; - -class GitAPI -{ - git_repository* m_Repo = nullptr; - git_index* m_Index = nullptr; - git_oid m_FirstCommitOid; - - std::string m_CurrentBranch = ""; - -public: - GitAPI(bool fsyncEnable); - ~GitAPI(); - - bool InitializeRepository(const std::string& srcPath); - void OpenRepository(const std::string& repoPath); - - bool IsHEADExists(); - bool IsRepositoryClonedFrom(const std::string& depotPath); - std::string DetectLatestCL(); - - git_oid CreateBlob(const std::vector& data); - - void CreateIndex(); - void SetActiveBranch(const std::string& branchName); - void AddFileToIndex(const std::string& relativePath, const std::vector& contents, const bool plusx); - void RemoveFileFromIndex(const std::string& relativePath); - - std::string Commit( - const std::string& depotPath, - const std::string& cl, - const std::string& user, - const std::string& email, - const int& timezone, - const std::string& desc, - const int64_t& timestamp, - const std::string& mergeFromStream); - void CloseIndex(); -}; +/* + * Copyright (c) 2022 Salesforce, Inc. + * All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + * For full license text, see the LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause + */ +#pragma once + +#include +#include +#include + +#include "common.h" +#include "git2/oid.h" + +struct git_repository; + +class GitAPI +{ + git_repository* m_Repo = nullptr; + git_index* m_Index = nullptr; + git_oid m_FirstCommitOid; + + std::string m_CurrentBranch = ""; + +public: + GitAPI(bool fsyncEnable); + ~GitAPI(); + + bool InitializeRepository(const std::string& srcPath); + void OpenRepository(const std::string& repoPath); + + bool IsHEADExists(); + bool IsRepositoryClonedFrom(const std::string& depotPath); + std::string DetectLatestCL(); + + git_oid CreateBlob(const std::vector& data); + + void CreateIndex(); + void SetActiveBranch(const std::string& branchName); + void AddFileToIndex(const std::string& relativePath, const std::vector& contents, const bool plusx); + void RemoveFileFromIndex(const std::string& relativePath); + + std::string Commit( + const std::string& depotPath, + const std::string& cl, + const std::string& user, + const std::string& email, + const int& timezone, + std::string desc, + const int64_t& timestamp, + const std::string& mergeFromStream); + void CloseIndex(); +}; diff --git a/p4-fusion/main.cc b/p4-fusion/main.cc index c2ea1629..2e35d405 100644 --- a/p4-fusion/main.cc +++ b/p4-fusion/main.cc @@ -313,29 +313,30 @@ int Main(int argc, char** argv) ThreadPool::GetSingleton()->Initialize(networkThreads); SUCCESS("Created " << ThreadPool::GetSingleton()->GetThreadCount() << " threads in thread pool"); - int startupDownloadsCount = 0; - + // Go in the chronological order size_t lastDownloadedCL = 0; for (size_t currentCL = 0; currentCL < changes.size() && currentCL < lookAhead; currentCL++) { ChangeList& cl = changes.at(currentCL); - + // Start gathering changed files with `p4 describe` or `p4 filelog` cl.PrepareDownload(branchSet); - + lastDownloadedCL = currentCL; } - + // This is intentionally put in a separate loop. // We want to submit `p4 describe` commands before sending any of the `p4 print` commands. // Gives ~15% perf boost. + int startupDownloadsCount = 0; for (size_t currentCL = 0; currentCL <= lastDownloadedCL; currentCL++) { ChangeList& cl = changes.at(currentCL); // Start running `p4 print` on changed files when the describe is finished cl.StartDownload(printBatch); + startupDownloadsCount++; } SUCCESS("Queued first " << startupDownloadsCount << " CLs up until CL " << changes.at(lastDownloadedCL).number << " for downloading");