diff options
25 files changed, 453 insertions, 158 deletions
diff --git a/.github/workflows/uffizzi-build.yml b/.github/workflows/uffizzi-build.yml new file mode 100644 index 000000000..58c7e5866 --- /dev/null +++ b/.github/workflows/uffizzi-build.yml @@ -0,0 +1,89 @@ +name: Build PR Image +on: + pull_request: + types: [opened, synchronize, reopened, closed] + +jobs: + build-application: + name: Build and Push `lazygit` + runs-on: ubuntu-latest + if: ${{ github.event_name != 'pull_request' || github.event.action != 'closed' }} + outputs: + tags: ${{ steps.meta.outputs.tags }} + steps: + - name: Checkout git repo + uses: actions/checkout@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + - name: Generate UUID image name + id: uuid + run: echo "UUID_APP_TAG=$(uuidgen)" >> $GITHUB_ENV + - name: Docker metadata + id: meta + uses: docker/metadata-action@v3 + with: + images: registry.uffizzi.com/${{ env.UUID_APP_TAG }} + tags: type=raw,value=60d + - name: Build and Push Image to registry.uffizzi.com ephemeral registry + uses: docker/build-push-action@v2 + with: + push: true + context: ./ + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + file: ./uffizzi/DockerfileTtyd + cache-from: type=gha + cache-to: type=gha,mode=max + + + render-compose-file: + name: Render Docker Compose File + # Pass output of this workflow to another triggered by `workflow_run` event. + runs-on: ubuntu-latest + needs: + - build-application + outputs: + compose-file-cache-key: ${{ steps.hash.outputs.hash }} + steps: + - name: Checkout git repo + uses: actions/checkout@v3 + - name: Render Compose File + run: | + APP_IMAGE=$(echo ${{ needs.build-application.outputs.tags }}) + export APP_IMAGE + # Render simple template from environment variables. + envsubst < ./uffizzi/docker-compose.uffizzi.yml > docker-compose.rendered.yml + cat docker-compose.rendered.yml + - name: Upload Rendered Compose File as Artifact + uses: actions/upload-artifact@v3 + with: + name: preview-spec + path: docker-compose.rendered.yml + retention-days: 2 + - name: Serialize PR Event to File + run: | + cat << EOF > event.json + ${{ toJSON(github.event) }} + + EOF + - name: Upload PR Event as Artifact + uses: actions/upload-artifact@v3 + with: + name: preview-spec + path: event.json + retention-days: 2 + + delete-preview: + name: Call for Preview Deletion + runs-on: ubuntu-latest + if: ${{ github.event.action == 'closed' }} + steps: + # If this PR is closing, we will not render a compose file nor pass it to the next workflow. + - name: Serialize PR Event to File + run: echo '${{ toJSON(github.event) }}' > event.json + - name: Upload PR Event as Artifact + uses: actions/upload-artifact@v3 + with: + name: preview-spec + path: event.json + retention-days: 2 diff --git a/.github/workflows/uffizzi-preview.yml b/.github/workflows/uffizzi-preview.yml new file mode 100644 index 000000000..ce8a9c46f --- /dev/null +++ b/.github/workflows/uffizzi-preview.yml @@ -0,0 +1,84 @@ +name: Deploy Uffizzi Preview + +on: + workflow_run: + workflows: + - "Build PR Image" + types: + - completed + + +jobs: + cache-compose-file: + name: Cache Compose File + runs-on: ubuntu-latest + outputs: + compose-file-cache-key: ${{ env.COMPOSE_FILE_HASH }} + pr-number: ${{ env.PR_NUMBER }} + steps: + - name: 'Download artifacts' + # Fetch output (zip archive) from the workflow run that triggered this workflow. + uses: actions/github-script@v6 + with: + script: | + let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: context.payload.workflow_run.id, + }); + let matchArtifact = allArtifacts.data.artifacts.filter((artifact) => { + return artifact.name == "preview-spec" + })[0]; + let download = await github.rest.actions.downloadArtifact({ + owner: context.repo.owner, + repo: context.repo.repo, + artifact_id: matchArtifact.id, + archive_format: 'zip', + }); + let fs = require('fs'); + fs.writeFileSync(`${process.env.GITHUB_WORKSPACE}/preview-spec.zip`, Buffer.from(download.data)); + - name: 'Unzip artifact' + run: unzip preview-spec.zip + - name: Read Event into ENV + run: | + echo 'EVENT_JSON<<EOF' >> $GITHUB_ENV + cat event.json >> $GITHUB_ENV + echo 'EOF' >> $GITHUB_ENV + - name: Hash Rendered Compose File + id: hash + # If the previous workflow was triggered by a PR close event, we will not have a compose file artifact. + if: ${{ fromJSON(env.EVENT_JSON).action != 'closed' }} + run: echo "COMPOSE_FILE_HASH=$(md5sum docker-compose.rendered.yml | awk '{ print $1 }')" >> $GITHUB_ENV + - name: Cache Rendered Compose File + if: ${{ fromJSON(env.EVENT_JSON).action != 'closed' }} + uses: actions/cache@v3 + with: + path: docker-compose.rendered.yml + key: ${{ env.COMPOSE_FILE_HASH }} + + - name: Read PR Number From Event Object + id: pr + run: echo "PR_NUMBER=${{ fromJSON(env.EVENT_JSON).number }}" >> $GITHUB_ENV + + - name: DEBUG - Print Job Outputs + if: ${{ runner.debug }} + run: | + echo "PR number: ${{ env.PR_NUMBER }}" + echo "Compose file hash: ${{ env.COMPOSE_FILE_HASH }}" + cat event.json + deploy-uffizzi-preview: + name: Use Remote Workflow to Preview on Uffizzi + needs: + - cache-compose-file + uses: UffizziCloud/preview-action/.github/workflows/reusable.yaml@v2.6.1 + with: + # If this workflow was triggered by a PR close event, cache-key will be an empty string + # and this reusable workflow will delete the preview deployment. + compose-file-cache-key: ${{ needs.cache-compose-file.outputs.compose-file-cache-key }} + compose-file-cache-path: docker-compose.rendered.yml + server: https://app.uffizzi.com + pr-number: ${{ needs.cache-compose-file.outputs.pr-number }} + permissions: + contents: read + pull-requests: write + id-token: write
\ No newline at end of file @@ -22,7 +22,7 @@ A simple terminal UI for git commands, written in Go with the [gocui](https://gi </p> <p align="center"> -<!-- sponsors --><a href="https://github.com/atecce"><img src="https://github.com/atecce.png" width="60px" alt="" /></a><a href="https://github.com/intabulas"><img src="https://github.com/intabulas.png" width="60px" alt="" /></a><a href="https://github.com/peppy"><img src="https://github.com/peppy.png" width="60px" alt="" /></a><a href="https://github.com/piot"><img src="https://github.com/piot.png" width="60px" alt="" /></a><a href="https://github.com/blacky14"><img src="https://github.com/blacky14.png" width="60px" alt="" /></a><a href="https://github.com/rgwood"><img src="https://github.com/rgwood.png" width="60px" alt="" /></a><a href="https://github.com/oliverguenther"><img src="https://github.com/oliverguenther.png" width="60px" alt="" /></a><a href="https://github.com/pawanjay176"><img src="https://github.com/pawanjay176.png" width="60px" alt="" /></a><a href="https://github.com/bdach"><img src="https://github.com/bdach.png" width="60px" alt="" /></a><a href="https://github.com/naoey"><img src="https://github.com/naoey.png" width="60px" alt="" /></a><a href="https://github.com/jryom"><img src="https://github.com/jryom.png" width="60px" alt="" /></a><a href="https://github.com/carstengehling"><img src="https://github.com/carstengehling.png" width="60px" alt="" /></a><a href="https://github.com/ceuk"><img src="https://github.com/ceuk.png" width="60px" alt="" /></a><a href="https://github.com/akospwc"><img src="https://github.com/akospwc.png" width="60px" alt="" /></a><a href="https://github.com/Xetera"><img src="https://github.com/Xetera.png" width="60px" alt="" /></a><a href="https://github.com/HoldenLucas"><img src="https://github.com/HoldenLucas.png" width="60px" alt="" /></a><a href="https://github.com/barbados-clemens"><img src="https://github.com/barbados-clemens.png" width="60px" alt="" /></a><a href="https://github.com/nartc"><img src="https://github.com/nartc.png" width="60px" alt="" /></a><a href="https://github.com/"><img src="https://github.com/.png" width="60px" alt="" /></a><a href="https://github.com/matejcik"><img src="https://github.com/matejcik.png" width="60px" alt="" /></a><a href="https://github.com/lucatume"><img src="https://github.com/lucatume.png" width="60px" alt="" /></a><a href="https://github.com/dbabiak"><img src="https://github.com/dbabiak.png" width="60px" alt="" /></a><a href="https://github.com/davidlattimore"><img src="https://github.com/davidlattimore.png" width="60px" alt="" /></a><a href="https://github.com/zach-fuller"><img src="https://github.com/zach-fuller.png" width="60px" alt="" /></a><a href="https://github.com/escrafford"><img src="https://github.com/escrafford.png" width="60px" alt="" /></a><a href="https://github.com/davdroman"><img src="https://github.com/davdroman.png" width="60px" alt="" /></a><a href="https://github.com/KowalskiPiotr98"><img src="https://github.com/KowalskiPiotr98.png" width="60px" alt="" /></a><a href="https://github.com/IvanZuy"><img src="https://github.com/IvanZuy.png" width="60px" alt="" /></a><a href="https://github.com/nicholascloud"><img src="https://github.com/nicholascloud.png" width="60px" alt="" /></a><a href="https://github.com/topher200"><img src="https://github.com/topher200.png" width="60px" alt="" /></a><a href="https://github.com/PhotonQuantum"><img src="https://github.com/PhotonQuantum.png" width="60px" alt="" /></a><a href="https://github.com/GitSquared"><img src="https://github.com/GitSquared.png" width="60px" alt="" /></a><a href="https://github.com/ava1ar"><img src="https://github.com/ava1ar.png" width="60px" alt="" /></a><a href="https://github.com/alqh"><img src="https://github.com/alqh.png" width="60px" alt="" /></a><a href="https://github.com/pedropombeiro"><img src="https://github.com/pedropombeiro.png" width="60px" alt="" /></a><a href="https://github.com/minidfx"><img src="https://github.com/minidfx.png" width="60px" alt="" /></a><a href="https://github.com/JoeKlemmer"><img src="https://github.com/JoeKlemmer.png" width="60px" alt="" /></a><a href="https://github.com/MikaelElkiaer"><img src="https://github.com/MikaelElkiaer.png" width="60px" alt="" /></a><a href="https://github.com/smoogipoo"><img src="https://github.com/smoogipoo.png" width="60px" alt="" /></a><a href="https://github.com/ColonelBucket8"><img src="https://github.com/ColonelBucket8.png" width="60px" alt="" /></a><a href="https://github.com/mutewinter"><img src="https://github.com/mutewinter.png" width="60px" alt="" /></a><a href="https://github.com/tobi"><img src="https://github.com/tobi.png" width="60px" alt="" /></a><a href="https://github.com/benmacleod"><img src="https://github.com/benmacleod.png" width="60px" alt="" /></a><a href="https://github.com/benbfortis"><img src="https://github.com/benbfortis.png" width="60px" alt="" /></a><a href="https://github.com/jakewarren"><img src="https://github.com/jakewarren.png" width="60px" alt="" /></a><a href="https://github.com/huettern"><img src="https://github.com/huettern.png" width="60px" alt="" /></a><a href="https://github.com/tgpholly"><img src="https://github.com/tgpholly.png" width="60px" alt="" /></a><a href="https://github.com/Fuzznimp"><img src="https://github.com/Fuzznimp.png" width="60px" alt="" /></a><a href="https://github.com/crab-apple"><img src="https://github.com/crab-apple.png" width="60px" alt="" /></a><a href="https://github.com/Tommylans"><img src="https://github.com/Tommylans.png" width="60px" alt="" /></a><a href="https://github.com/jacktrusler"><img src="https://github.com/jacktrusler.png" width="60px" alt="" /></a><a href="https://github.com/pablosproject"><img src="https://github.com/pablosproject.png" width="60px" alt="" /></a><a href="https://github.com/jisantuc"><img src="https://github.com/jisantuc.png" width="60px" alt="" /></a><a href="https://github.com/kahgeh"><img src="https://github.com/kahgeh.png" width="60px" alt="" /></a><a href="https://github.com/broneks"><img src="https://github.com/broneks.png" width="60px" alt="" /></a><a href="https://github.com/zabil"><img src="https://github.com/zabil.png" width="60px" alt="" /></a><a href="https://github.com/naoric"><img src="https://github.com/naoric.png" width="60px" alt="" /></a><a href="https://github.com/GianniBYoung"><img src="https://github.com/GianniBYoung.png" width="60px" alt="" /></a><a href="https://github.com/kannapoix"><img src="https://github.com/kannapoix.png" width="60px" alt="" /></a><a href="https://github.com/jliendo"><img src="https://github.com/jliendo.png" width="60px" alt="" /></a><a href="https://github.com/bitprophet"><img src="https://github.com/bitprophet.png" width="60px" alt="" /></a><!-- sponsors --> +<!-- sponsors --><a href="https://github.com/atecce"><img src="https://github.com/atecce.png" width="60px" alt="" /></a><a href="https://github.com/intabulas"><img src="https://github.com/intabulas.png" width="60px" alt="" /></a><a href="https://github.com/peppy"><img src="https://github.com/peppy.png" width="60px" alt="" /></a><a href="https://github.com/piot"><img src="https://github.com/piot.png" width="60px" alt="" /></a><a href="https://github.com/blacky14"><img src="https://github.com/blacky14.png" width="60px" alt="" /></a><a href="https://github.com/rgwood"><img src="https://github.com/rgwood.png" width="60px" alt="" /></a><a href="https://github.com/oliverguenther"><img src="https://github.com/oliverguenther.png" width="60px" alt="" /></a><a href="https://github.com/pawanjay176"><img src="https://github.com/pawanjay176.png" width="60px" alt="" /></a><a href="https://github.com/bdach"><img src="https://github.com/bdach.png" width="60px" alt="" /></a><a href="https://github.com/naoey"><img src="https://github.com/naoey.png" width="60px" alt="" /></a><a href="https://github.com/jryom"><img src="https://github.com/jryom.png" width="60px" alt="" /></a><a href="https://github.com/carstengehling"><img src="https://github.com/carstengehling.png" width="60px" alt="" /></a><a href="https://github.com/ceuk"><img src="https://github.com/ceuk.png" width="60px" alt="" /></a><a href="https://github.com/akospwc"><img src="https://github.com/akospwc.png" width="60px" alt="" /></a><a href="https://github.com/Xetera"><img src="https://github.com/Xetera.png" width="60px" alt="" /></a><a href="https://github.com/HoldenLucas"><img src="https://github.com/HoldenLucas.png" width="60px" alt="" /></a><a href="https://github.com/barbados-clemens"><img src="https://github.com/barbados-clemens.png" width="60px" alt="" /></a><a href="https://github.com/nartc"><img src="https://github.com/nartc.png" width="60px" alt="" /></a><a href="https://github.com/"><img src="https://github.com/.png" width="60px" alt="" /></a><a href="https://github.com/matejcik"><img src="https://github.com/matejcik.png" width="60px" alt="" /></a><a href="https://github.com/lucatume"><img src="https://github.com/lucatume.png" width="60px" alt="" /></a><a href="https://github.com/dbabiak"><img src="https://github.com/dbabiak.png" width="60px" alt="" /></a><a href="https://github.com/davidlattimore"><img src="https://github.com/davidlattimore.png" width="60px" alt="" /></a><a href="https://github.com/zach-fuller"><img src="https://github.com/zach-fuller.png" width="60px" alt="" /></a><a href="https://github.com/escrafford"><img src="https://github.com/escrafford.png" width="60px" alt="" /></a><a href="https://github.com/davdroman"><img src="https://github.com/davdroman.png" width="60px" alt="" /></a><a href="https://github.com/KowalskiPiotr98"><img src="https://github.com/KowalskiPiotr98.png" width="60px" alt="" /></a><a href="https://github.com/IvanZuy"><img src="https://github.com/IvanZuy.png" width="60px" alt="" /></a><a href="https://github.com/nicholascloud"><img src="https://github.com/nicholascloud.png" width="60px" alt="" /></a><a href="https://github.com/topher200"><img src="https://github.com/topher200.png" width="60px" alt="" /></a><a href="https://github.com/PhotonQuantum"><img src="https://github.com/PhotonQuantum.png" width="60px" alt="" /></a><a href="https://github.com/GitSquared"><img src="https://github.com/GitSquared.png" width="60px" alt="" /></a><a href="https://github.com/ava1ar"><img src="https://github.com/ava1ar.png" width="60px" alt="" /></a><a href="https://github.com/alqh"><img src="https://github.com/alqh.png" width="60px" alt="" /></a><a href="https://github.com/pedropombeiro"><img src="https://github.com/pedropombeiro.png" width="60px" alt="" /></a><a href="https://github.com/minidfx"><img src="https://github.com/minidfx.png" width="60px" alt="" /></a><a href="https://github.com/JoeKlemmer"><img src="https://github.com/JoeKlemmer.png" width="60px" alt="" /></a><a href="https://github.com/MikaelElkiaer"><img src="https://github.com/MikaelElkiaer.png" width="60px" alt="" /></a><a href="https://github.com/smoogipoo"><img src="https://github.com/smoogipoo.png" width="60px" alt="" /></a><a href="https://github.com/ColonelBucket8"><img src="https://github.com/ColonelBucket8.png" width="60px" alt="" /></a><a href="https://github.com/mutewinter"><img src="https://github.com/mutewinter.png" width="60px" alt="" /></a><a href="https://github.com/tobi"><img src="https://github.com/tobi.png" width="60px" alt="" /></a><a href="https://github.com/benmacleod"><img src="https://github.com/benmacleod.png" width="60px" alt="" /></a><a href="https://github.com/benbfortis"><img src="https://github.com/benbfortis.png" width="60px" alt="" /></a><a href="https://github.com/jakewarren"><img src="https://github.com/jakewarren.png" width="60px" alt="" /></a><a href="https://github.com/huettern"><img src="https://github.com/huettern.png" width="60px" alt="" /></a><a href="https://github.com/tgpholly"><img src="https://github.com/tgpholly.png" width="60px" alt="" /></a><a href="https://github.com/Fuzznimp"><img src="https://github.com/Fuzznimp.png" width="60px" alt="" /></a><a href="https://github.com/crab-apple"><img src="https://github.com/crab-apple.png" width="60px" alt="" /></a><a href="https://github.com/Tommylans"><img src="https://github.com/Tommylans.png" width="60px" alt="" /></a><a href="https://github.com/jacktrusler"><img src="https://github.com/jacktrusler.png" width="60px" alt="" /></a><a href="https://github.com/pablosproject"><img src="https://github.com/pablosproject.png" width="60px" alt="" /></a><a href="https://github.com/jisantuc"><img src="https://github.com/jisantuc.png" width="60px" alt="" /></a><a href="https://github.com/zabil"><img src="https://github.com/zabil.png" width="60px" alt="" /></a><a href="https://github.com/kannapoix"><img src="https://github.com/kannapoix.png" width="60px" alt="" /></a><a href="https://github.com/jliendo"><img src="https://github.com/jliendo.png" width="60px" alt="" /></a><a href="https://github.com/bitprophet"><img src="https://github.com/bitprophet.png" width="60px" alt="" /></a><a href="https://github.com/kohane27"><img src="https://github.com/kohane27.png" width="60px" alt="" /></a><a href="https://github.com/cschmatzler"><img src="https://github.com/cschmatzler.png" width="60px" alt="" /></a><a href="https://github.com/viktorburian"><img src="https://github.com/viktorburian.png" width="60px" alt="" /></a><a href="https://github.com/the-shank"><img src="https://github.com/the-shank.png" width="60px" alt="" /></a><a href="https://github.com/tayleighr"><img src="https://github.com/tayleighr.png" width="60px" alt="" /></a><!-- sponsors --> </p> ## Elevator Pitch @@ -150,15 +150,10 @@ sudo eopkg install lazygit ### Ubuntu ```sh -LAZYGIT_VERSION=$(curl -s "https://api.github.com/repos/jesseduffield/lazygit/releases/latest" | grep '"tag_name":' | sed -E 's/.*"v*([^"]+)".*/\1/') -``` - -```sh +LAZYGIT_VERSION=$(curl -s "https://api.github.com/repos/jesseduffield/lazygit/releases/latest" | grep -Po '"tag_name": "v\K[^"]*') curl -Lo lazygit.tar.gz "https://github.com/jesseduffield/lazygit/releases/latest/download/lazygit_${LAZYGIT_VERSION}_Linux_x86_64.tar.gz" -``` - -```sh -sudo tar xf lazygit.tar.gz -C /usr/local/bin lazygit +tar xf lazygit.tar.gz lazygit +sudo install lazygit /usr/local/bin ``` Verify the correct installation of lazygit: diff --git a/docs/Config.md b/docs/Config.md index 4bcac2064..6a9be62e9 100644 --- a/docs/Config.md +++ b/docs/Config.md @@ -62,20 +62,21 @@ gui: showIcons: false commandLogSize: 8 splitDiff: 'auto' # one of 'auto' | 'always' + skipRewordInEditorWarning: false # for skipping the confirmation before launching the reword editor git: paging: colorArg: always useConfig: false commit: signOff: false - verbose: false + verbose: default # one of 'default' | 'always' | 'never' merging: # only applicable to unix users manualCommit: false # extra args passed to `git merge`, e.g. --no-ff args: '' log: - # one of date-order, author-date-order, topo-order. + # one of date-order, author-date-order, topo-order or default. # topo-order makes it easier to read the git log graph, but commits may not # appear chronologically. See https://git-scm.com/docs/git-log#_commit_ordering order: 'topo-order' @@ -190,6 +191,8 @@ keybinding: viewResetOptions: 'D' fetch: 'f' toggleTreeView: '`' + openMergeTool: 'M' + openStatusFilter: '<c-b>' branches: createPullRequest: 'o' viewPullRequestOptions: 'O' diff --git a/pkg/commands/git_commands/branch.go b/pkg/commands/git_commands/branch.go index 117427778..a71e365ea 100644 --- a/pkg/commands/git_commands/branch.go +++ b/pkg/commands/git_commands/branch.go @@ -2,19 +2,12 @@ package git_commands import ( "fmt" - "regexp" "strings" "github.com/jesseduffield/lazygit/pkg/commands/oscommands" "github.com/jesseduffield/lazygit/pkg/utils" ) -// this takes something like: -// * (HEAD detached at 264fc6f5) -// remotes -// and returns '264fc6f5' as the second match -const CurrentBranchNameRegex = `(?m)^\*.*?([^ ]*?)\)?$` - type BranchCommands struct { *GitCommon } @@ -41,19 +34,18 @@ func (self *BranchCommands) CurrentBranchInfo() (BranchInfo, error) { DetachedHead: false, }, nil } - output, err := self.cmd.New("git branch --contains").DontLog().RunWithOutput() + output, err := self.cmd.New(`git branch --points-at=HEAD --format="%(HEAD)%00%(objectname)%00%(refname)"`).DontLog().RunWithOutput() if err != nil { return BranchInfo{}, err } for _, line := range utils.SplitLines(output) { - re := regexp.MustCompile(CurrentBranchNameRegex) - match := re.FindStringSubmatch(line) - if len(match) > 0 { - branchName = match[1] - displayBranchName := match[0][2:] + split := strings.Split(strings.TrimRight(line, "\r\n"), "\x00") + if len(split) == 3 && split[0] == "*" { + sha := split[1] + displayName := split[2] return BranchInfo{ - RefName: branchName, - DisplayName: displayBranchName, + RefName: sha, + DisplayName: displayName, DetachedHead: true, }, nil } diff --git a/pkg/commands/git_commands/branch_test.go b/pkg/commands/git_commands/branch_test.go index 94456c0f8..2fdf7d9c2 100644 --- a/pkg/commands/git_commands/branch_test.go +++ b/pkg/commands/git_commands/branch_test.go @@ -181,26 +181,30 @@ func TestBranchCurrentBranchInfo(t *testing.T) { }, }, { - "falls back to git `git branch --contains` if symbolic-ref fails", + "falls back to git `git branch --points-at=HEAD` if symbolic-ref fails", oscommands.NewFakeRunner(t). Expect(`git symbolic-ref --short HEAD`, "", errors.New("error")). - Expect(`git branch --contains`, "* (HEAD detached at 8982166a)", nil), + Expect(`git branch --points-at=HEAD --format="%(HEAD)%00%(objectname)%00%(refname)"`, "*\x006f71c57a8d4bd6c11399c3f55f42c815527a73a4\x00(HEAD detached at 6f71c57a)\n", nil), func(info BranchInfo, err error) { assert.NoError(t, err) - assert.EqualValues(t, "8982166a", info.RefName) - assert.EqualValues(t, "(HEAD detached at 8982166a)", info.DisplayName) + assert.EqualValues(t, "6f71c57a8d4bd6c11399c3f55f42c815527a73a4", info.RefName) + assert.EqualValues(t, "(HEAD detached at 6f71c57a)", info.DisplayName) assert.True(t, info.DetachedHead) }, }, { - "handles a detached head", + "handles a detached head (LANG=zh_CN.UTF-8)", oscommands.NewFakeRunner(t). Expect(`git symbolic-ref --short HEAD`, "", errors.New("error")). - Expect(`git branch --contains`, "* (HEAD detached at 123abcd)", nil), + Expect( + `git branch --points-at=HEAD --format="%(HEAD)%00%(objectname)%00%(refname)"`, + "*\x00679b0456f3db7c505b398def84e7d023e5b55a8d\x00(头指针在 679b0456 分离)\n"+ + " \x00679b0456f3db7c505b398def84e7d023e5b55a8d\x00refs/heads/master\n", + nil), func(info BranchInfo, err error) { assert.NoError(t, err) - assert.EqualValues(t, "123abcd", info.RefName) - assert.EqualValues(t, "(HEAD detached at 123abcd)", info.DisplayName) + assert.EqualValues(t, "679b0456f3db7c505b398def84e7d023e5b55a8d", info.RefName) + assert.EqualValues(t, "(头指针在 679b0456 分离)", info.DisplayName) assert.True(t, info.DetachedHead) }, }, @@ -208,7 +212,7 @@ func TestBranchCurrentBranchInfo(t *testing.T) { "bubbles up error if there is one", oscommands.NewFakeRunner(t). Expect(`git symbolic-ref --short HEAD`, "", errors.New("error")). - Expect(`git branch --contains`, "", errors.New("error")), + Expect(`git branch --points-at=HEAD --format="%(HEAD)%00%(objectname)%00%(refname)"`, "", errors.New("error")), func(info BranchInfo, err error) { assert.Error(t, err) assert.EqualValues(t, "", info.RefName) diff --git a/pkg/commands/git_commands/commit.go b/pkg/commands/git_commands/commit.go index be06cb245..b5293a2ff 100644 --- a/pkg/commands/git_commands/commit.go +++ b/pkg/commands/git_commands/commit.go @@ -74,9 +74,12 @@ func (self *CommitCommands) signoffFlag() string { } func (self *CommitCommands) verboseFlag() string { - if self.UserConfig.Git.Commit.Verbose { + switch self.config.UserConfig.Git.Commit.Verbose { + case "always": return " --verbose" - } else { + case "never": + return " --no-verbose" + default: return "" } } diff --git a/pkg/commands/git_commands/commit_loader.go b/pkg/commands/git_commands/commit_loader.go index f89f62c48..00e2f80ad 100644 --- a/pkg/commands/git_commands/commit_loader.go +++ b/pkg/commands/git_commands/commit_loader.go @@ -426,7 +426,10 @@ func (self *CommitLoader) getLogCmd(opts GetCommitsOptions) oscommands.ICmdObj { config := self.UserConfig.Git.Log - orderFlag := "--" + config.Order + orderFlag := "" + if config.Order != "default" { + orderFlag = " --" + config.Order + } allFlag := "" if opts.All { allFlag = " --all" @@ -434,7 +437,7 @@ func (self *CommitLoader) getLogCmd(opts GetCommitsOptions) oscommands.ICmdObj { return self.cmd.New( fmt.Sprintf( - "git -c log.showSignature=false log %s %s %s --oneline %s%s --abbrev=%d%s", + "git -c log.showSignature=false log %s%s%s --oneline %s%s --abbrev=%d%s", self.cmd.Quote(opts.RefName), orderFlag, allFlag, @@ -446,14 +449,4 @@ func (self *CommitLoader) getLogCmd(opts GetCommitsOptions) oscommands.ICmdObj { ).DontLog() } -var prettyFormat = fmt.Sprintf( - "--pretty=format:\"%%H%s%%at%s%%aN%s%%ae%s%%d%s%%p%s%%s\"", - NULL_CODE, - NULL_CODE, - NULL_CODE, - NULL_CODE, - NULL_CODE, - NULL_CODE, -) - -const NULL_CODE = "%x00" +const prettyFormat = `--pretty=format:"%H%x00%at%x00%aN%x00%ae%x00%d%x00%p%x00%s"` diff --git a/pkg/commands/git_commands/commit_loader_test.go b/pkg/commands/git_commands/commit_loader_test.go index ab6d5a105..aa20ae802 100644 --- a/pkg/commands/git_commands/commit_loader_test.go +++ b/pkg/commands/git_commands/commit_loader_test.go @@ -27,6 +27,7 @@ func TestGetCommits(t *testing.T) { runner *oscommands.FakeCmdObjRunner expectedCommits []*models.Commit expectedError error + logOrder string rebaseMode enums.RebaseMode currentBranchName string opts GetCommitsOptions @@ -35,18 +36,20 @@ func TestGetCommits(t *testing.T) { scenarios := []scenario{ { testName: "should return no commits if there are none", + logOrder: "topo-order", rebaseMode: enums.REBASE_MODE_NONE, currentBranchName: "master", opts: GetCommitsOptions{RefName: "HEAD", IncludeRebaseCommits: false}, runner: oscommands.NewFakeRunner(t). Expect(`git merge-base "HEAD" "HEAD"@{u}`, "b21997d6b4cbdf84b149d8e6a2c4d06a8e9ec164", nil). - Expect(`git -c log.showSignature=false log "HEAD" --topo-order --oneline --pretty=format:"%H%x00%at%x00%aN%x00%ae%x00%d%x00%p%x00%s" --abbrev=40`, "", nil), + Expect(`git -c log.showSignature=false log "HEAD" --topo-order --oneline --pretty=format:"%H%x00%at%x00%aN%x00%ae%x00%d%x00%p%x00%s" --abbrev=40`, "", nil), expectedCommits: []*models.Commit{}, expectedError: nil, }, { testName: "should return commits if they are present", + logOrder: "topo-order", rebaseMode: enums.REBASE_MODE_NONE, currentBranchName: "master", opts: GetCommitsOptions{RefName: "HEAD", IncludeRebaseCommits: false}, @@ -54,7 +57,7 @@ func TestGetCommits(t *testing.T) { // here it's seeing which commits are yet to be pushed Expect(`git merge-base "HEAD" "HEAD"@{u}`, "b21997d6b4cbdf84b149d8e6a2c4d06a8e9ec164", nil). // here it's actually getting all the commits in a formatted form, one per line - Expect(`git -c log.showSignature=false log "HEAD" --topo-order --oneline --pretty=format:"%H%x00%at%x00%aN%x00%ae%x00%d%x00%p%x00%s" --abbrev=40`, commitsOutput, nil). + Expect(`git -c log.showSignature=false log "HEAD" --topo-order --oneline --pretty=format:"%H%x00%at%x00%aN%x00%ae%x00%d%x00%p%x00%s" --abbrev=40`, commitsOutput, nil). // here it's seeing where our branch diverged from the |