Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Discussion] Share tips, tricks and custom commands with Fork community #961

Open
Lonli-Lokli opened this issue Sep 24, 2020 · 31 comments
Open

Comments

@Lonli-Lokli
Copy link

I believe with custom commands many of us have a plenty variety of ideas how to enrich usability.
Lets share it with each other!

  1. Copy branch name to clipboard (thanks @DanPristupov )
    image
@DanPristupov
Copy link
Contributor

Thank you for starting this topic. A bit later I will add some useful examples and a short roadmap.

@DanPristupov DanPristupov pinned this issue Sep 25, 2020
@Otiel
Copy link

Otiel commented Oct 9, 2020

Here are some I use:

  {
    "name": "Merge Commit Into Current Branch",
    "target": "revision",
    "action": {
      "type": "process",
      "path": "$git",
      "args": "merge $sha",
      "showOutput": false,
      "waitForExit": false
    }
  },
  {
    "name": "Rebase (Rebase Merges) to Here...",
    "target": "revision",
    "action": {
      "type": "process",
      "path": "$git",
      "args": "rebase --rebase-merges $SHA",
      "showOutput": false,
      "waitForExit": true
    }
  },
  {
    "name": "Rebase Interactively (Rebase Merges) to Here...",
    "target": "revision",
    "action": {
      "type": "process",
      "path": "$git",
      "args": "rebase --interactive --rebase-merges $SHA",
      "showOutput": false,
      "waitForExit": true
    }
  },
  {
    "name": "Copy Commit Abbreviated SHA",
    "target": "revision",
    "action": {
      "type": "process",
      "path": "$sh",
      "args": "-c 'echo $sha | clip'",
      "showOutput": false,
      "waitForExit": false
    }
  }

@carlolars
Copy link

Right-click on a commit in the log and do a "fixup!" commit of the staged changes:

  {
    "name": "Fixup! staged changes for '$sha'",
    "target": "revision",
    "action": {
      "type": "process",
      "path": "$git",
      "args": "commit --fixup $SHA",
      "showOutput": false,
      "waitForExit": false
    }
  },

@jerone
Copy link

jerone commented Dec 7, 2020

Here is mine:

[
  {
    "name": "Change author to me",
    "target": "revision",
    "action": {
      "type": "process",
      "path": "$git",
      "args": "commit --amend --author \"John Doe <[email protected]>\" --no-edit",
      "showOutput": true,
      "waitForExit": true
    }
  },
  {
    "name": "Open in ConEmu",
    "target": "repository",
    "action": {
      "type": "process",
      "path": "C:\\Program Files\\ConEmu\\ConEmu64.exe",
      "args": "",
      "showOutput": false,
      "waitForExit": false
    }
  },
  {
    "name": "Open in Windows Terminal",
    "target": "repository",
    "action": {
      "type": "sh",
      "script": "wt -d \\\"$path\\\"",
      "showOutput": false,
      "waitForExit": false
    }
  },
  {
    "name": "Branches...",
    "target": "revision",
    "action": {
      "type": "sh",
      "script": "git branch -a --contains $SHA",
      "showOutput": true,
      "waitForExit": true
    }
  },
  {
    "name": "Find merge commit",
    "target": "revision",
    "action": {
      "type": "sh",
      "script": "git log --merges $SHA..",
      "showOutput": true,
      "waitForExit": true
    }
  }
]

@dsbert
Copy link

dsbert commented Dec 9, 2020

Unless I'm mistaken, most of these commands have been added into the application as standard features.

Mistaken

@asontu
Copy link

asontu commented Dec 9, 2020

@dsbert No they have not, the devil is in the details:

rebase --rebase-merges != vanilla rebase
abbreviated sha != SHA

@brhmira
Copy link

brhmira commented Jan 13, 2021

Hi, I am using a custom command "git push -o merge_request.create ... etc.", the command itself automatically creates a merge request".
When running in cmd, there is a output message. For example: "Everything up-to-date". Unfortunately, I was not able to forward the git result message to Fork UI. When running a custom command, there is a window "Custom command completed", no details. Thx.

@DanPristupov
Copy link
Contributor

@brhmira

This happens because "Everything up-to-date" is written to the stderr and the result window doesn't show error output by default. I need to think about how to handle this properly.

You can see the full output in the activity manager (the button in the left bottom corner in the status control on the toolbar).

Screenshot 2021-01-13 at 15 09 59

@tkolb-recom
Copy link

  {
    "name": "Cherry-pick commit (append message)",
    "target": "revision",
    "ui": {
      "title": "Cherry-Pick",
      "description": "This will pick the selected commit to the current branch. Proceed?",
      "buttons": [
        {
          "title": "OK",
          "action": {
            "type": "process",
            "path": "$git",
            "args": "cherry-pick -x $SHA",
            "showOutput": true,
            "waitForExit": true
          }
        },
        {
          "title": "Cancel",
          "action": {
            "type": "cancel"
          }
        }
      ]
    }
  }

@DrunkRussianGun
Copy link

DrunkRussianGun commented Mar 20, 2021

I'm actively using these, but they require aliases from here (except "Copy path" file command).

[
  {
    "name": "Fetch and rebase",
    "target": "ref",
    "refTargets": [
      "localbranch",
      "remotebranch"
    ],
    "action": {
      "type": "process",
      "path": "$git",
      "args": "febase $name",
      "showOutput": false,
      "waitForExit": true
    }
  },
  {
    "name": "Deliver",
    "target": "ref",
    "refTargets": [
      "localbranch",
      "remotebranch"
    ],
    "action": {
      "type": "process",
      "path": "$git",
      "args": "deliver $name",
      "showOutput": false,
      "waitForExit": true
    }
  },
  {
    "name": "Delete merged branches",
    "target": "ref",
    "refTargets": [
      "localbranch",
      "remotebranch"
    ],
    "action": {
      "type": "process",
      "path": "$git",
      "args": "del-merged $name",
      "showOutput": false,
      "waitForExit": true
    }
  },
  {
    "name": "Copy abbreviated commit SHA",
    "target": "revision",
    "action": {
      "type": "process",
      "path": "$git",
      "args": "cp-sha $SHA",
      "showOutput": false,
      "waitForExit": false
    }
  },
  {
    "name": "Copy commit full message",
    "target": "revision",
    "action": {
      "type": "process",
      "path": "$git",
      "args": "cp-message $SHA",
      "showOutput": false,
      "waitForExit": false
    }
  },
  {
    "name": "Reset files to here",
    "target": "revision",
    "action": {
      "type": "process",
      "path": "$git",
      "args": "reset-files $SHA",
      "showOutput": false,
      "waitForExit": true
    }
  },,
  {
    "name": "Fixup",
    "target": "revision",
    "action": {
      "type": "process",
      "path": "$git",
      "args": "fixup $SHA",
      "showOutput": false,
      "waitForExit": true
    }
  },
  {
    "name": "Copy path",
    "target": "file",
    "action": {
      "type": "process",
      "path": "$sh",
      "args": "-c 'echo \"$filepath\" | clip'",
      "showOutput": false,
      "waitForExit": false
    }
  }
]

@decadence
Copy link

decadence commented Apr 6, 2021

Here is my 2 cents: make file executable for repository and git archive on selected commit.

{
    "name": "Make file executable",
    "target": "file",
    "action": {
      "type": "process",
      "path": "$git",
      "args": "update-index --chmod=+x $filepath",
      "showOutput": true,
      "waitForExit": true
    }
  },
{
  "name": "Make commit archive",
  "target": "revision",
  "action": {
    "type": "process",
    "path": "$git",
    "args": "archive --output=./$SHA.zip $SHA",
    "showOutput": true,
    "waitForExit": true
  }
}

@Lonli-Lokli
Copy link
Author

Lonli-Lokli commented Jun 22, 2021

Here is mine:

[
  {
    "name": "Change author to me",
    "target": "revision",
    "action": {
      "type": "process",
      "path": "$git",
      "args": "commit --amend --author \"John Doe <[email protected]>\" --no-edit",
      "showOutput": true,
      "waitForExit": true
    }
  }
]

I believe for change author it's better to use this
git -c user.name=“New Name" -c user.email=[email protected] commit --amend --reset-author --no-edit

@jerone
Copy link

jerone commented Jun 22, 2021

I believe for change author it's better to use this
git -c user.name=“New Name" -c user.email=[email protected] commit --amend --reset-author --no-edit

@Lonli-Lokli Why is that better?

@Lonli-Lokli
Copy link
Author

Lonli-Lokli commented Jun 22, 2021

@jerone because original command will change the author to the name specified, but the committer will be set to your configured user in git config user.name and git config user.email.

I am still trying to understand what is the possible way to do it with some selected commits

@kv1dr
Copy link

kv1dr commented Jun 30, 2021

Checkout only one file from specific commit:

[
  {
    "name": "Checkout file",
    "target": "file",
    "action": {
      "type": "process",
      "path": "$git",
      "args": "checkout -m $sha -- $filepath",
      "showOutput": false,
      "waitForExit": true
    }
  }
]

@DanPristupov
Copy link
Contributor

@kv1dr right click on a file in the 'Changes' view -> Reset File to state at commit.

@kv1dr
Copy link

kv1dr commented Jun 30, 2021

@kv1dr right click on a file in the 'Changes' view -> Reset File to state at commit.

Oh, I didn't know that option exists. But it's still missing from File Tree tab.

@asontu
Copy link

asontu commented Jul 12, 2021

@Otiel how does your Rebase interactively with merges ever work? Since there's no GUI, every time I tried so far it has completely broken my Git into a corrupted state of half-rebase. Usually warrants restarting my machine to be able to manually remove rebase-folders under the .git folder.

@Otiel
Copy link

Otiel commented Jul 12, 2021

@asontu

  1. Click on the custom command.
  2. Edit git-rebase-todo in the opened editor.
  3. Save git-rebase-todo / close the editor.
  4. Fork should refresh and proceed with the rebase.

If you don't have an editor opening at step 2, that's probably because you're missing some config. If so, open the Shell from Fork (in order to modify the correct .gitconfig file), then run the following to use VS Code as editor:

git config --global core.editor "code --wait"

(see here for other common editors)

@AndyWright-ct
Copy link

AndyWright-ct commented Jan 12, 2022

If you have hub installed (https://github.com/github/hub)

Target: Repository
Name: Hub Sync
Type: Action
Action: Sh Command
	Script: hub sync
    [x] Wait for Exit
	[ ] Always Show Output -- up to you

This will remove merged branches and update all other branches, without you having to switch to the branch and pull -- a great time saver :)

@BensonleeHC
Copy link

Is there arg for previous SHA? thanks!!

@Rossbro2
Copy link

I am still trying to understand what is the possible way to do it with some selected commits

Has anyone figured out how to change the author of a specific commit and not just head?

👀 @Lonli-Lokli

@psylenced
Copy link

Is there arg for previous SHA? thanks!!

You can use HEAD~1 (1 behind head) or 123456789~1 (1 behind sha 123456789).

So at a guess $sha~1 (maybe with a space) might work?

@kapsiR
Copy link

kapsiR commented Jun 29, 2022

Nice file custom command to show the encoding of a file on Windows:

{
    "name": "file --mime-encoding",
    "target": "file",
    "action": {
      "type": "process",
      "path": "C:\\Program Files\\Git\\usr\\bin\\file.exe",
      "args": "--mime-encoding $filepath",
      "showOutput": true,
      "waitForExit": true
    }
  }

I'm not sure, if you have to install Git Bash to have file.exe available

@jerone
Copy link

jerone commented Sep 21, 2022

@DanPristupov Would it be possible to support environment variable in paths:

%LocalAppData%\Microsoft\WindowsApps\wt.exe

Results in the following error:
image

I expect it to resolve to (which I know exists):

C:\Users\<username>\AppData\Local\Microsoft\WindowsApps\wt.exe

@kapsiR
Copy link

kapsiR commented Sep 21, 2022

@jerone I created an issue for this some time ago, please upvote it with a reaction 😉

@StephenHodgson
Copy link

This comes in handy when I want to do either powershell or bash profiles. Love that it opens a tab for either.

  "ShellTool": {
    "Type": "Custom",
    "ApplicationPath": "%USERPROFILE%\\AppData\\Local\\Microsoft\\WindowsApps\\wt.exe",
    "Arguments": "new-tab -p \"PowerShell\" -d . ; new-tab -p \"Bash\" -d ."
  },

@JeReT
Copy link

JeReT commented Dec 20, 2022

We had the problem that we have a public version, a public hotfix version, where people already can preview upcoming fixes AND another public version for upcoming features. We are using gitflow and extract the version number from the latest tag.
The problem was that when we made a hotfix, it started from master were also the new features (release branches) are merged into. So we couldn't separate active major/minor and patch versions in git.

What I came up with was another branch next to develop and master and a script to finish a hotfix into that branch (and also the others). This way we can have a separation between hotfix and new feature versions.
Here is the script:

export LANG=C.UTF-8

cur=$(git branch --show-current)
version=$(basename $cur)

if [[ $cur == $name ]]
then
    echo You cannot finish $cur into itself.
    exit 1
fi

if [[ $cur == master || $cur == develop ]]
then
    echo finishing into master or develop is not allowed with this command.
    exit 1
fi

echo checking out master and merging
git checkout master
git merge --no-ff $cur

echo checking out develop and merging
git checkout develop
git merge --no-ff $cur

echo checking out $name, merging and create tag $version
git checkout $name
git merge --no-ff $cur

echo deleting branch
git branch -d $cur

#for some reason the script stops after tagging
echo creating tag
git tag -a $version -m "Merge branch $cur"

echo FINISHED

@DanPristupov
Do you have an idea why the command doesn't proceed after the tag creation command? e.g. echo FINISHED is never called / doesn't appear in the log.

EDIT:
found out how to properly share. Here also a version that doesn't merge into master and develop:

[
  {
    "name": "Finish here",
    "target": "ref",
    "refTargets": [
      "localbranch",
      "remotebranch"
    ],
    "action": {
      "type": "sh",
      "script": "export LANG=C.UTF-8\r\n\r\ncur=$(git branch --show-current)\r\nversion=$(basename $cur)\r\n\r\nif [[ $cur == $name ]]\r\nthen\r\n    echo You cannot finish $cur into itself.\r\n    exit 1\r\nfi\r\n\r\necho checking out $name and merging\r\ngit checkout $name\r\ngit merge --no-ff $cur\r\n\r\necho deleting branch\r\ngit branch -d $cur\r\n\r\n#for some reason the script stops after tagging\r\necho creating tag\r\ngit tag -a $version -m \"Merge branch $cur\"\r\n\r\necho FINISHED",
      "showOutput": false,
      "waitForExit": true
    }
  },
  {
    "name": "Finish here, master & develop",
    "target": "ref",
    "refTargets": [
      "localbranch",
      "remotebranch"
    ],
    "action": {
      "type": "sh",
      "script": "export LANG=C.UTF-8\r\n\r\ncur=$(git branch --show-current)\r\nversion=$(basename $cur)\r\n\r\nif [[ $cur == $name ]]\r\nthen\r\n    echo You cannot finish $cur into itself.\r\n    exit 1\r\nfi\r\n\r\nif [[ $cur == master || $cur == develop ]]\r\nthen\r\n    echo finishing into master or develop is not allowed with this command.\r\n    exit 1\r\nfi\r\n\r\necho checking out master and merging\r\ngit checkout master\r\ngit merge --no-ff $cur\r\n\r\necho checking out develop and merging\r\ngit checkout develop\r\ngit merge --no-ff $cur\r\n\r\necho checking out $name and merging\r\ngit checkout $name\r\ngit merge --no-ff $cur\r\n\r\necho deleting branch\r\ngit branch -d $cur\r\n\r\n#for some reason the script stops after tagging\r\necho creating tag\r\ngit tag -a $version -m \"Merge branch $cur\"\r\n\r\necho FINISHED",
      "showOutput": false,
      "waitForExit": true
    }
  }
]

@ravindUwU
Copy link

ravindUwU commented Mar 29, 2023

I use a custom command to git merge --ff-only (#95) 😊

{
	"name": "Merge (FF-only) into Current Branch",
	"target": "ref",
	"refTargets": [
		"localbranch"
	],
	"action": {
		"type": "process",
		"path": "$git",
		"args": "merge $name --ff-only",
		"showOutput": true,
		"waitForExit": true
	}
}

Just because I can't seem to find this documented anywhere (or perhaps missed it), %LocalAppData%\Fork\custom-commands.json stores custom commands' JSON representation.

@palaniraja
Copy link

Here is mine, Local PR without a commit so I can view consolidated changes
similar to the one above, but meets my need. No additional dialog, replicate same behavior as my PR rules and I can use better diff tools than the default bitbucket one.

{
    "action" : {
      "script" : "git merge ${ref} --no-ff --no-commit",
      "showOutput" : false,
      "type" : "sh",
      "waitForExit" : true
    },
    "name" : "Review Branch",
    "referenceTargets" : [
      "localBranch",
      "remoteBranch"
    ],
    "target" : "reference"
  }

@havrlisan
Copy link

havrlisan commented Oct 14, 2023

I fell in love with the Lean Branching idea, but I'm too lazy to press the UI buttons Sync, Finish, and then checkout back to the working branch, so I created a command that does all of that on one click:

  {
    "action" : {
      "script" : "commits=$(git rev-list --count develop..${ref})\n\ngit stash save\ngit update-ref refs/heads/develop refs/remotes/origin/develop\ngit checkout develop\n\nif [ $commits == 1 ]; then\n  git merge ${ref}\nelse\n  git merge ${ref} --no-ff\nfi\n  \ngit push origin refs/heads/develop --verbose\ngit checkout ${ref}\ngit -c core.commentChar=^ rebase refs/heads/develop\ngit stash pop stash@{0}",
      "showOutput" : false,
      "type" : "sh",
      "waitForExit" : true
    },
    "name" : "Lean Branching - Rebase '${ref}' onto 'develop'",
    "refTargets" : [
      "localbranch"
    ],
    "target" : "ref"
  }

The command will also use merge --no-ff the same way as the Finish button does.

Edit: also added automatic stash save/pop.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests