Repository: steveukx/git-js
Pull request #634 (2021-06-09 07:38:27)

mergeFromTo
fix: updates the documentation for `mergeFromTo` to more closely represent its functionality (see #50 for the original requirement).

Move `mergeFromTo` to the TypeScript api and add tests to assert the enforcing of argument types.


Patch:
diff --git a/readme.md b/readme.md
index 0a14f8a..d6255bb 100644
--- a/readme.md
+++ b/readme.md
@@ -262,8 +262,9 @@ For type details of the response for each of the tasks, please see the [TypeScri
    When the merge failed, the MergeSummary contains summary detail for why the merge failed and which files
    prevented the merge.
 
-- `.mergeFromTo(from, to [, options])` - merge from one branch to another, similar to `.merge` but with the
-   `from` and `to` supplied as strings separately to any additional the [options](#how-to-specify-options).
+- `.mergeFromTo(remote, branch [, options])` - merge from the specified branch into the currently checked out branch,
+    similar to `.merge` but with the `remote` and `branch` supplied as strings separately to any additional 
+   [options](#how-to-specify-options).
 
 ## git mv
 
@@ -271,7 +272,6 @@ For type details of the response for each of the tasks, please see the [TypeScri
 
 - `.mv(from, to)` move all files in the `from` array to the `to` directory
 
-
 ## git pull
 
 - `.pull([options])` pulls all updates from the default tracked remote, any arguments supported by
diff --git a/src/git.js b/src/git.js
index 4038d6a..3708f43 100644
--- a/src/git.js
+++ b/src/git.js
@@ -514,49 +514,6 @@ Git.prototype.remote = function (options, then) {
    );
 };
 
-/**
- * Merges from one branch to another, equivalent to running `git merge ${from} $[to}`, the `options` argument can
- * either be an array of additional parameters to pass to the command or null / omitted to be ignored.
- *
- * @param {string} from
- * @param {string} to
- */
-Git.prototype.mergeFromTo = function (from, to) {
-   if (!(filterString(from) && filterString(to))) {
-      return this._runTask(configurationErrorTask(
-         `Git.mergeFromTo requires that the 'from' and 'to' arguments are supplied as strings`
-      ));
-   }
-
-   return this._runTask(
-      mergeTask([from, to, ...getTrailingOptions(arguments)]),
-      trailingFunctionArgument(arguments, false),
-   );
-};
-
-/**
- * Runs a merge, `options` can be either an array of arguments
- * supported by the [`git merge`](https://git-scm.com/docs/git-merge)
- * or an options object.
- *
- * Conflicts during the merge result in an error response,
- * the response type whether it was an error or success will be a MergeSummary instance.
- * When successful, the MergeSummary has all detail from a the PullSummary
- *
- * @param {Object | string[]} [options]
- * @param {Function} [then]
- * @returns {*}
- *
- * @see ./responses/MergeSummary.js
- * @see ./responses/PullSummary.js
- */
-Git.prototype.merge = function () {
-   return this._runTask(
-      mergeTask(getTrailingOptions(arguments)),
-      trailingFunctionArgument(arguments),
-   );
-};
-
 /**
  * Call any `git tag` function with arguments passed as an array of strings.
  *
diff --git a/src/lib/simple-git-api.ts b/src/lib/simple-git-api.ts
index 5e56fc9..b4d67d8 100644
--- a/src/lib/simple-git-api.ts
+++ b/src/lib/simple-git-api.ts
@@ -2,6 +2,7 @@ import { SimpleGitBase } from '../../typings';
 import { taskCallback } from './task-callback';
 import { changeWorkingDirectoryTask } from './tasks/change-working-directory';
 import { initTask } from './tasks/init';
+import { mergeTask } from './tasks/merge';
 import { pushTask } from './tasks/push';
 import { statusTask } from './tasks/status';
 import { configurationErrorTask, straightThroughStringTask } from './tasks/task';
@@ -58,6 +59,26 @@ export class SimpleGitApi implements SimpleGitBase {
       );
    }
 
+   merge() {
+      return this._runTask(
+         mergeTask(getTrailingOptions(arguments)),
+         trailingFunctionArgument(arguments),
+      );
+   }
+
+   mergeFromTo (remote: string, branch: string) {
+      if (!(filterString(remote) && filterString(branch))) {
+         return this._runTask(configurationErrorTask(
+            `Git.mergeFromTo requires that the 'remote' and 'branch' arguments are supplied as strings`
+         ));
+      }
+
+      return this._runTask(
+         mergeTask([remote, branch, ...getTrailingOptions(arguments)]),
+         trailingFunctionArgument(arguments, false),
+      );
+   }
+
    outputHandler (handler: outputHandler) {
       this._executor.outputHandler = handler;
       return this;
diff --git a/typings/simple-git.d.ts b/typings/simple-git.d.ts
index ebae27c..fca24b6 100644
--- a/typings/simple-git.d.ts
+++ b/typings/simple-git.d.ts
@@ -35,6 +35,28 @@ export interface SimpleGitBase {
 
    init(callback?: types.SimpleGitTaskCallback<resp.InitResult>): Response<resp.InitResult>;
 
+   /**
+    * Runs a merge, `options` can be either an array of arguments
+    * supported by the [`git merge`](https://git-scm.com/docs/git-merge)
+    * or an options object.
+    *
+    * Conflicts during the merge result in an error response,
+    * the response type whether it was an error or success will be a MergeSummary instance.
+    * When successful, the MergeSummary has all detail from a the PullSummary
+    *
+    * @see https://github.com/steveukx/git-js/blob/master/src/responses/MergeSummary.js
+    * @see https://github.com/steveukx/git-js/blob/master/src/responses/PullSummary.js
+    */
+   merge(options: types.TaskOptions, callback?: types.SimpleGitTaskCallback<resp.MergeResult>): Response<resp.MergeResult>;
+
+   /**
+    * Merges from one branch to another, equivalent to running `git merge ${remote} ${branch}`, the `options` argument can
+    * either be an array of additional parameters to pass to the command or null / omitted to be ignored.
+    */
+   mergeFromTo<E extends GitError>(remote: string, branch: string, options?: types.TaskOptions, callback?: types.SimpleGitTaskCallback<resp.MergeResult, E>): Response<resp.MergeResult>;
+
+   mergeFromTo<E extends GitError>(remote: string, branch: string, callback?: types.SimpleGitTaskCallback<resp.MergeResult, E>): Response<resp.MergeResult>;
+
    /**
     * Sets a handler function to be called whenever a new child process is created, the handler function will be called
     * with the name of the command being run and the stdout & stderr streams used by the ChildProcess.
@@ -385,31 +407,6 @@ export interface SimpleGit extends SimpleGitBase {
     */
    log<T = types.DefaultLogFields>(options?: types.TaskOptions | types.LogOptions<T>, callback?: types.SimpleGitTaskCallback<resp.LogResult<T>>): Response<resp.LogResult<T>>;
 
-   /**
-    * Runs a merge, `options` can be either an array of arguments
-    * supported by the [`git merge`](https://git-scm.com/docs/git-merge)
-    * or an options object.
-    *
-    * Conflicts during the merge result in an error response,
-    * the response type whether it was an error or success will be a MergeSummary instance.
-    * When successful, the MergeSummary has all detail from a the PullSummary
-    *
-    * @see https://github.com/steveukx/git-js/blob/master/src/responses/MergeSummary.js
-    * @see https://github.com/steveukx/git-js/blob/master/src/responses/PullSummary.js
-    */
-   merge(options: types.TaskOptions, callback?: types.SimpleGitTaskCallback<resp.MergeResult>): Response<resp.MergeResult>;
-
-   /**
-    * Merges from one branch to another, equivalent to running `git merge ${from} $[to}`, the `options` argument can
-    * either be an array of additional parameters to pass to the command or null / omitted to be ignored.
-    *
-    * - from branch to merge from.
-    * - to branch to merge to.
-    */
-   mergeFromTo<E extends GitError>(from: string, to: string, options?: types.TaskOptions, callback?: types.SimpleGitTaskCallback<resp.MergeResult, E>): Response<resp.MergeResult>;
-
-   mergeFromTo<E extends GitError>(from: string, to: string, callback?: types.SimpleGitTaskCallback<resp.MergeResult, E>): Response<resp.MergeResult>;
-
    /**
     * Mirror a git repo
     *


Test patch:
diff --git a/test/unit/merge.spec.ts b/test/unit/merge.spec.ts
index 836ac8c..696ff7d 100644
--- a/test/unit/merge.spec.ts
+++ b/test/unit/merge.spec.ts
@@ -1,6 +1,7 @@
 import { promiseError } from '@kwsites/promise-result';
 import {
    assertExecutedCommands,
+   assertGitError,
    assertGitResponseError,
    closeWithError,
    closeWithSuccess,
@@ -13,6 +14,8 @@ import { MergeResult, SimpleGit, SimpleGitTaskCallback } from 'typings';
 import { MergeSummaryDetail } from '../../src/lib/responses/MergeSummary';
 import { parseMergeResult } from '../../src/lib/parsers/parse-merge';
 
+import { TaskConfigurationError } from '../..';
+
 describe('merge', () => {
 
    describe('api', () => {
@@ -35,6 +38,10 @@ describe('merge', () => {
          assertExecutedCommands('merge', 'aaa', 'bbb');
       });
 
+      it('mergeFromTo requires remote and branch strings', async () => {
+         assertGitError(await promiseError((git.mergeFromTo as any)([])), 'supplied as strings', TaskConfigurationError);
+      });
+
       it('mergeFromToWithOptions', async () => {
          git.mergeFromTo('aaa', 'bbb', ['x', 'y'], jest.fn());
          await closeWithSuccess();