diff --git a/Ghidra/Features/Base/src/main/help/help/topics/VersionControl/project_repository.htm b/Ghidra/Features/Base/src/main/help/help/topics/VersionControl/project_repository.htm
index d3e5d0c5dd..4cb185cee3 100644
--- a/Ghidra/Features/Base/src/main/help/help/topics/VersionControl/project_repository.htm
+++ b/Ghidra/Features/Base/src/main/help/help/topics/VersionControl/project_repository.htm
@@ -14,7 +14,7 @@
- Project Repository
+ Project Repository
Ghidra supports the concept of a project repository such that files in the repository
can be versioned. Versioning allows you to track file
diff --git a/Ghidra/Features/VersionTracking/certification.manifest b/Ghidra/Features/VersionTracking/certification.manifest
index fe6191d51e..3e8f42116b 100644
--- a/Ghidra/Features/VersionTracking/certification.manifest
+++ b/Ghidra/Features/VersionTracking/certification.manifest
@@ -56,6 +56,7 @@ src/main/help/help/topics/VersionTrackingPlugin/images/VersionTrackingTool.png||
src/main/help/help/topics/VersionTrackingPlugin/images/accepted_fully_applied.png||GHIDRA||reviewed||END|
src/main/help/help/topics/VersionTrackingPlugin/images/accepted_fully_considered.png||GHIDRA||reviewed||END|
src/main/help/help/topics/VersionTrackingPlugin/images/accepted_warning.png||GHIDRA||reviewed||END|
+src/main/help/help/topics/VersionTrackingPlugin/images/start-here.png||Tango Icons - Public Domain|||tango icon set|END|
src/main/help/help/topics/VersionTrackingPlugin/providers/VT_Apply_Options.html||GHIDRA||||END|
src/main/help/help/topics/VersionTrackingPlugin/providers/VT_Functions_Table.html||GHIDRA||||END|
src/main/help/help/topics/VersionTrackingPlugin/providers/VT_Implied_Matches_Table.html||GHIDRA||||END|
diff --git a/Ghidra/Features/VersionTracking/ghidra_scripts/AddVTSessionToVersionControl.java b/Ghidra/Features/VersionTracking/ghidra_scripts/AddVTSessionToVersionControl.java
new file mode 100644
index 0000000000..7b1f1dc021
--- /dev/null
+++ b/Ghidra/Features/VersionTracking/ghidra_scripts/AddVTSessionToVersionControl.java
@@ -0,0 +1,70 @@
+/* ###
+ * IP: GHIDRA
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//Script that enables user to add an existing Version Tracking Session to version control. This
+//is meant to to be used when project is a shared project and when running in headless mode
+//since it is simple add a VTSession to version control from the project manager when running in
+//GUI mode.
+//@category Version Tracking
+import ghidra.app.script.GhidraScript;
+import ghidra.features.base.values.GhidraValuesMap;
+import ghidra.framework.model.DomainFile;
+import ghidra.util.MessageType;
+
+public class AddVTSessionToVersionControl extends GhidraScript {
+
+ @Override
+ public void run() throws Exception {
+
+ GhidraValuesMap startupValues = new GhidraValuesMap();
+
+ startupValues.defineProjectFile("Select Version Tracking Session", "/");
+ startupValues.defineString("Enter commit message", "Commiting session to version control");
+
+ startupValues.setValidator((valueMap, status) -> {
+
+ if (!valueMap.hasValue("Select Version Tracking Session")) {
+ status.setStatusText("Must select a Version Tracking Session!", MessageType.ERROR);
+ return false;
+ }
+
+ if (!valueMap.hasValue("Enter commit message")) {
+ status.setStatusText("Must enter a commit message!", MessageType.ERROR);
+ return false;
+ }
+ return true;
+ });
+
+ startupValues = askValues(
+ "Enter Version Tracking Session info for adding to source control:", "", startupValues);
+
+ DomainFile sessionDF = startupValues.getProjectFile("Select Version Tracking Session");
+ String commitMsg = startupValues.getString("Enter commit message");
+
+ if (sessionDF.isVersioned()) {
+ println("Chosen session is already in version control");
+ return;
+ }
+
+ // add session to version control and do not keep checkout out
+ sessionDF.addToVersionControl(commitMsg, false, monitor);
+
+ println(sessionDF.getName() + " was successfully added to version control.");
+
+ }
+
+
+
+}
diff --git a/Ghidra/Features/VersionTracking/ghidra_scripts/AutoVersionTrackingScript.java b/Ghidra/Features/VersionTracking/ghidra_scripts/AutoVersionTrackingScript.java
index 3daa33f5d6..e53d1162a0 100644
--- a/Ghidra/Features/VersionTracking/ghidra_scripts/AutoVersionTrackingScript.java
+++ b/Ghidra/Features/VersionTracking/ghidra_scripts/AutoVersionTrackingScript.java
@@ -14,37 +14,77 @@
* limitations under the License.
*/
-// A script that runs Auto Version Tracking given the options set in one of the following ways:
+// A script that runs Auto Version Tracking such that the current program in the tool is the
+// destination program and the user is prompted to choose the source program. The user must also
+// choose a name for a new Version Tracking Session. The script cannot run using an existing session.
+// There are many options that can be set in one of the following ways:
// 1. If script is run from the CodeBrowser, the GUI options are set in a pop up dialog by user.
-// 2. If script is run in headless mode either the defaults provided by the script are used or the
-// user can specify a script to be run that sets the options. See example script
+// 2. If script is run in headless mode either the default options provided by the script are used
+// or the user can specify a script to be run that sets the options. See example script
// SetAutoVersionTrackingOptionsScript that can be copied and updated to reflect the users
// desired options.
//
-// NOTE: This is an example to show how run this script in headless mode
+// HEADLESS MODE NON-SHARED PROJECT:
+//
+// This is an example to show how run this script in headless mode against a local non-shared
+// project
//
// /support/analyzeHeadless.bat/sh c:/MyGhidraProjectFolder
-// MyProjectName/OptionalFolderContainingProgram -process Program1.exe -postScript
+// MyProjectName/OptionalFolderContainingDestProgram -process DestinationProgram.exe -postScript
// MyOptionsSetupScript -postScript AutoVersionTrackingScript.java "/FolderContainingSession"
-// "MySessionName" true "/OptionalFolderContainingProgram/Program2.exe"
+// "MySessionName" "/OptionalFolderContainingSourceProgram/SourceProgram.exe"
//
-//
-// NOTE: The first program will be analyzed for you if it is not already analyzed (and if you
-// do not include the -noanalysis option) as it is part of the typical analyzeHeadless run.
-// The second program must be analyzed prior to running the script as the headless analyzer
-// itself knows nothing about the file other than as a given option name. This is true in
-// both GUI and headless mode.
-//
-// NOTE: The second to last parameter is to identify whether the first listed program
-// is the source program or not. True means first program is source program and second
-// program is destination program. False means second program is source program and first
-// program is destination program. This is important if you want the correct markup to be
-// applied from the source to destination program.
+// NOTE: The destination program will be analyzed for you if it is not already analyzed (and if
+// you do not include the -noanalysis option) as it is part of the typical analyzeHeadless
+// run. The source program must be analyzed prior to running the script as the headless
+// analyzer itself knows nothing about the file other than as a given option name. This is
+// true in both GUI and headless mode.
//
// NOTE: The options setup script is optional. It is only necessary if users want to change the
-// default options. To use it make a copy of the example one and save to a new script. You
-// You may need to add the -scriptPath to the headless run so it will find your script.
+// other default options that are not settable on the headless command line. To use an
+// options script, make a copy of the example one (SetAutoVersionTrackingOptionsScript)
+// and save it with a new script file name. Then use the -postScript headless argument to
+// run the options script before the second -postScript argument to run the
+// AutoVersionTrackingScript. Depending on where you save your script, you might also need
+// to add the -scriptPath to the headless run so it will find your script.
//
+// SHARED PROJECT MODE FROM GUI
+//
+// From the GUI, this script can run on local project files contained in the shared project or
+// those that have been added to source control. If the destination program has been added to
+// version control but is not checked out, the user will be prompted to checkout the file.
+// If the file is not checked-out the script will not proceed. User is responsible for checking
+// in changes to the destination file made by the script if they want the changes added. After
+// the script is run, if user wants to add the session to version control they can.
+//
+// SHARED PROJECT MODE FROM HEADLESS MODE:
+//
+// If running this script in headless mode on a shared project, both source and destination
+// programs must have already been added to version control before running the script or the
+// script will not be able to locate the programs because the only programs visible to it will
+// be those in the shared repository project.
+//
+// The headless shared project run will be different from the non-shared project in terms of how
+// to tell it where the project location is. Instead of specifying a project location and
+// project name, the user must instead specify the Ghidra Server repository URL.
+//
+// Also, there are necessary extra arguments to the headless run in order to connect to the
+// server and commit the destination program changes to the server.
+//
+// This is an example command line for running this script in headless shared project mode:
+//
+// /support/analyzeHeadless.bat/sh
+// ghidra://localhost:13100/MyProjectName/OptionalFolderContainingDestProgram -process
+// DestinationProgram.exe -postScript MyOptionsSetupScript -postScript
+// AutoVersionTrackingScript.java "/FolderContainingSession"
+// "MySessionName" "/OptionalFolderContainingSourceProgram/SourceProgram.exe"
+// optionalAddSessionToVersionControl -connect username -p -commit "my commit msg"
+//
+// NOTE: The Destination program being processed in the shared project headless run must not be
+// checked out by anyone prior to the run. The headless script expects the file to be in version
+// control but not checked out. The headless script will check it out, run the given scripts
+// against it then check in any changes with the given commit message.
+//
//@category Version Tracking
import ghidra.app.script.GhidraScript;
import ghidra.feature.vt.api.db.VTSessionDB;
@@ -63,29 +103,29 @@ import ghidra.util.task.TaskLauncher;
public class AutoVersionTrackingScript extends GhidraScript {
- private Program sourceProgram;
- private Program destinationProgram;
-
- @Override
- public void cleanup(boolean success) {
- if (sourceProgram != null && sourceProgram.isUsedBy(this)) {
- sourceProgram.release(this);
- }
- if (destinationProgram != null && destinationProgram.isUsedBy(this)) {
- destinationProgram.release(this);
- }
- super.cleanup(success);
- }
+ private static final int NUM_ARGS = 3;
@Override
public void run() throws Exception {
+
+ if(currentProgram == null) {
+ println("Please open the destination program.");
+ return;
+ }
+
+ Program destinationProgram = currentProgram;
+
+ if (!destinationProgram.canSave()) {
+ println("VT Session destination program " + destinationProgram.getName() +
+ " is read-only which prevents its use.");
+ return;
+ }
GhidraValuesMap startupValues = new GhidraValuesMap();
startupValues.defineProjectFolder("Version Tracking Session Folder", "/");
startupValues.defineString("Version Tracking Session Name");
- startupValues.defineBoolean("Check if current program is the Source Program", true);
- startupValues.defineProgram("Please select the other program");
+ startupValues.defineProjectFile("Please select the SOURCE program", "/");
startupValues.setValidator((valueMap, status) -> {
@@ -108,43 +148,38 @@ public class AutoVersionTrackingScript extends GhidraScript {
return false;
}
- if (!valueMap.hasValue("Please select the other program")) {
- status.setStatusText("Must choose second program!", MessageType.ERROR);
+ if (!valueMap.hasValue("Please select the SOURCE program")) {
+ status.setStatusText("Must choose a SOURCE program!", MessageType.ERROR);
return false;
}
return true;
});
startupValues = askValues("Enter Auto Version Tracking Information",
- "Changing these options will not change the corresponding tool options", startupValues);
+ "The currently opened program is assumed to be the DESTINATION program.",
+ startupValues);
DomainFolder folder = startupValues.getProjectFolder("Version Tracking Session Folder");
String name = startupValues.getString("Version Tracking Session Name");
- boolean isCurrentProgramSourceProg =
- startupValues.getBoolean("Check if current program is the Source Program");
// setting auto upgrade to isHeadless, will cause headless uses to auto upgrade, but in
- // Gui mode, will prompt before upgrading.
+ // GUI mode, will prompt before upgrading.
boolean autoUpgradeIfNeeded = isRunningHeadless();
- Program otherProgram = startupValues.getProgram("Please select the other program", this,
- state.getTool(), autoUpgradeIfNeeded);
+
+ DomainFile sourceProgramDF =
+ startupValues.getProjectFile("Please select the SOURCE program");
+ if (!Program.class.isAssignableFrom(sourceProgramDF.getDomainObjectClass())) {
+ println(sourceProgramDF.getContentType() + " file " + sourceProgramDF.getName() +
+ " may not be specified as the SOURCE Program.");
+ return;
+ }
+
+ Program sourceProgram = (Program) sourceProgramDF.getDomainObject(this, autoUpgradeIfNeeded,
+ false, monitor);
VTSession session = null;
try {
- if (isCurrentProgramSourceProg) {
- sourceProgram = currentProgram;
- destinationProgram = otherProgram;
- }
- else {
- destinationProgram = currentProgram;
- sourceProgram = otherProgram;
- }
-
- if (sourceProgram == null || destinationProgram == null) {
- return;
- }
-
// Need to end the script transaction or it interferes with vt things that need locks
end(true);
@@ -170,7 +205,7 @@ public class AutoVersionTrackingScript extends GhidraScript {
// See SetAutoVersionTrackingOptionsScript.java as an example
GhidraValuesMap stateOptionsMap =
(GhidraValuesMap) state.getEnvironmentVar("autoVTOptionsMap");
- if (optionsMap != null) {
+ if (stateOptionsMap != null) {
optionsMap = stateOptionsMap;
}
@@ -183,19 +218,35 @@ public class AutoVersionTrackingScript extends GhidraScript {
TaskLauncher.launch(autoVtTask);
// Save destination program and session changes
- otherProgram.save("Updated with Auto Version Tracking", monitor);
+ destinationProgram.save("Updated with Auto Version Tracking", monitor);
session.save();
println(autoVtTask.getStatusMsg());
}
+ catch (CancelledException e) {
+ // let finally clean up
+ return;
+ }
finally {
- if (otherProgram != null) {
- otherProgram.release(this);
+ if (sourceProgram != null) {
+ sourceProgram.release(this);
}
if (session != null) {
session.release(this);
+
}
}
+
+ // try adding to version control if it is a transient project (ie headless operating against
+ // a shared project repository
+ if (state.getProject().getProjectLocator().isTransient()) {
+
+ session.getDomainFile()
+ .addToVersionControl("Added new session + " + session.getName(), false,
+ monitor);
+ println("Added session " + session.getName() + " to version control.");
+ }
+
}
/**
diff --git a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/VT_Wizard.html b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/VT_Wizard.html
index a4debe9092..3c0638379d 100644
--- a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/VT_Wizard.html
+++ b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/VT_Wizard.html
@@ -401,6 +401,56 @@
version tracking session.
+ Open an Existing Session
+
+
+
+ To open an existing session you can do one of the following:
+
+
+ - Double click a an existing Session in the Project Manager window. Sessions can be
+ identified by the
icon next to their names.
+
+ - Drag an existing Session onto a running tool.
+
+ - Choose File->Open Session... from an open Version Tracking tool and select a Version Tracking Session.
+
+
+
+
+ Sessions in Project Repositories
+
+
+
+ Sessions can be versioned using Ghidra's
+ Project Repository
+ mechanism mostly in the same way programs or data archives can be with some
+ qualifications:
+
+
+ - Most shared project actions work for Sessions as they normally do, such as Add to
+ Version Control, Check In, History, ...
+
+ - When checking out a Session you must choose exclusive checkout because there is no
+ way to merge two Sessions that have been edited. Exclusive checkout will prevent others
+ from making changes to the session until an Undo Checkout is performed.
+
+ - In order for others to check out a Session that another user has added to source
+ control, the two programs used in creating the session must be first added to source
+ control. NOTE: The exact two programs used when creating the Session (not copies of the
+ programs) must be the ones added.
+
+ - When opening a versioned session in the active project the user may be prompted to perform a checkout if not currently checked-out.
+
+ - Opening a versioned session must have an exclusive checkout or it will fail on open. In addition, only a session within the active project may be opened (i.e., not a viewed project or URL-based access).
+
+ - NOTE: A session and its two programs must reside within the same project.
+
+
+
+
+
+
Provided by: Version Tracking Plugin
diff --git a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/start-here.png b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/start-here.png
new file mode 100644
index 0000000000..fc9b0497fe
Binary files /dev/null and b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/start-here.png differ