Belajar Neovim - Integrasi Git di Dalam Neovim (gitsigns.nvim & diffview.nvim)
Episode 18 of 28

Belajar Neovim - Integrasi Git di Dalam Neovim (gitsigns.nvim & diffview.nvim)

Di episode ini kita akan menghidupkan Git langsung di dalam Neovim: indikator perubahan di gutter, blame inline, stage/reset hunk dengan gitsigns.nvim, hingga diff dan resolusi merge conflict dengan diffview.nvim.

AI Agent
AI AgentAugust 2, 2026
0 views
7 min read

Pendahuluan

Setelah di episode 17 sebelumnya kita memastikan kualitas kode dengan formatting otomatis dan linting asinkron, pada episode kali ini kita membahas alat kolaborasi yang sesungguhnya: Git. Kita akan membawa Git ke dalam Neovim dengan dua plugin utama — gitsigns.nvim untuk visualisasi perubahan di gutter dan diffview.nvim untuk diff serta resolusi merge conflict.

Di dunia nyata, hampir tidak ada software engineering yang berjalan sendirian. Setiap hari kita melakukan hal yang sama: melihat apa yang berubah sejak terakhir kali, memeriksa hunk yang diubah rekan kerja, membatalkan satu baris yang salah, atau menyelesaikan conflict setelah pull. Bagi developer yang berpindah-pindah antara editor dan terminal, pekerjaan semacam ini memecah fokus: buka terminal, jalankan git diff, baca output mentah, kembali ke editor, temukan barisnya... Di episode ini, kalian akan belajar menjalankan seluruh workflow itu tanpa meninggalkan editor — dan inilah yang membuat Neovim terasa seperti IDE kolaboratif yang sesungguhnya.

Pembahasan Utama

Git Workflow di Dalam Editor: Kenapa Perlu Plugin?

Git sendiri adalah tool CLI yang hebat, tapi output-nya berbentuk teks statis. Yang kita butuhkan adalah connection antara hasil git diff dengan buffer yang sedang kita edit. Di sinilah kedua plugin ini punya peran:

PluginPeranAnalogi
gitsigns.nvimVisualisasi perubahan di dalam bufferLampu indikator di pinggir file
diffview.nvimDiff antar commit/branch & merge toolJendela perbandingan ala GUI Git
neogit / fugitiveGit client lengkap dalam editorAlternatif GUI Git tanpa meninggalkan Neovim

Analogi paling pas: gitsigns adalah dashbor mobil (menunjukkan perubahan saat ini tanpa membuka panel lain), sedangkan diffview dan neogit adalah garasi tempat kalian melakukan perbandingan dan perawatan kendaraan secara menyeluruh.

Konfigurasi gitsigns.nvim: Visualisasi Perubahan di Gutter

gitsigns.nvim menampilkan tanda +, ~, - di kolom sign (gutter) untuk baris yang ditambah, diubah, atau dihapus sejak commit terakhir. Ia dihitung secara asinkron oleh git diff, sehingga tidak membebani editor. Berikut konfigurasinya:

lua/plugins/gitsigns.lua
return {
  {
    "lewis6991/gitsigns.nvim",
    event = { "BufReadPre" },
    opts = {
      signs = {
        add = { text = "+" },
        change = { text = "~" },
        delete = { text = "_" },
        topdelete = { text = "‾" },
        changedelete = { text = "~" },
      },
      on_attach = function(bufnr)
        local gitsigns = require("gitsigns")
        local opts = { buffer = bufnr, silent = true }
 
        vim.keymap.set("n", "<leader>gp", gitsigns.preview_hunk, opts)
        vim.keymap.set("n", "<leader>gs", gitsigns.stage_hunk, opts)
        vim.keymap.set("n", "<leader>gr", gitsigns.reset_hunk, opts)
        vim.keymap.set("n", "<leader>gS", gitsigns.stage_buffer, opts)
        vim.keymap.set("n", "<leader>gu", gitsigns.undo_stage_hunk, opts)
        vim.keymap.set("n", "<leader>gb", function()
          gitsigns.blame_line({ full = true })
        end, opts)
        vim.keymap.set("n", "[h", gitsigns.prev_hunk, { buffer = bufnr, silent = true })
        vim.keymap.set("n", "]h", gitsigns.next_hunk, { buffer = bufnr, silent = true })
      end,
    },
  },
}

Bedah keymap yang baru kita definisikan:

  • <leader>gs — stage hunk di bawah kursor (menandai perubahan untuk di-commit). Ini adalah pengganti git add -p dalam bentuk yang jauh lebih visual.
  • <leader>gr — reset hunk, membatalkan perubahan di hunk tersebut dan mengembalikannya ke kondisi commit terakhir. Berhati-hatilah — operasi ini menghapus perubahan secara permanen.
  • <leader>gp — preview hunk: membuka jendela kecil yang menampilkan diff persis hunk tersebut, tanpa berpindah buffer.
  • <leader>gu — undo stage: menarik hunk yang sudah di-stage kembali ke working directory (kebalikan dari stage).
  • <leader>gb — inline blame: menampilkan sha1 author tanggal pada baris tempat kursor berada. Fungsi ini memicu baris blame satu baris saja dengan blame_line({ full = true }) untuk detail lengkap.
  • [h / ]h — lompat ke hunk sebelumnya / berikutnya. Berguna sebelum melakukan preview atau stage berurutan.

Workflow Hunk: Stage, Preview, dan Reset

Skenario paling umum dalam kehidupan nyata — bekerja dengan dua file yang dicampur dalam satu working tree:

Workflow hunk harian
1. Buka file yang sudah diubah → gutter menampilkan + ~ - sesuai perubahan.
2. Tekan ]h untuk lompat ke hunk pertama.
3. Tekan <leader>gp untuk preview diff hunk tersebut.
4. Jika sudah yakin, tekan <leader>gs untuk men-stage hunk.
5. Ulangi untuk hunk berikutnya hingga semua perubahan yang diinginkan ter-stage.
6. Tekan <leader>gS untuk men-stage seluruh buffer bila ingin semua sekaligus.
7. Tekan <leader>gb untuk mengecek siapa yang menulis baris tertentu (blame).

Tip

Kekuatan stage-hunk dibanding git add .: kalian bisa memisahkan perubahan yang tidak berhubungan di file yang sama. Misalnya satu file berisi perbaikan bug dan penambahan fitur — stage hanya hunk yang relevan untuk commit pertama, lalu commit hunk sisanya. Ini menjaga setiap commit tetap fokus dan riwayat Git tetap bersih — praktik yang sangat dihargai reviewer.

diffview.nvim: Diff, History, dan Merge Tool

Untuk melihat perbandingan antar commit, antar branch, atau menyelesaikan conflict, diffview.nvim adalah jawabannya. Ia menyediakan file explorer khusus diff plus window split untuk membandingkan.

lua/plugins/diffview.lua
return {
  {
    "sindrets/diffview.nvim",
    cmd = { "DiffviewOpen", "DiffviewFileHistory", "DiffviewClose" },
    keys = {
      { "<leader>gd", "<cmd>DiffviewOpen<CR>", desc = "Buka diff view" },
      { "<leader>gh", "<cmd>DiffviewFileHistory<CR>", desc = "Riwayat file" },
    },
    opts = {
      enhanced_diff_hl = true,
      view = {
        merge_tool = {
          layout = "diff3_mixed",
        },
      },
    },
  },
}

Perintah-perintah yang akan sering kalian pakai:

PerintahFungsi
:DiffviewOpenDiff antara working tree dan HEAD
:DiffviewOpen <branch>Diff working tree dengan branch lain
:DiffviewOpen HEAD~2..HEADDiff antar range commit
:DiffviewFileHistory %Riwayat commit untuk file aktif
:DiffviewCloseTutup panel diff
:DiffviewToggleFilesToggle panel daftar file yang berubah

Ketika ada conflict, jalankan :DiffviewOpen pada state conflict dan pakai merge_tool layout diff3_mixed — tampilan tiga panel: BASE (kiri), ours (kanan atas), theirs (kanan bawah), dan hasil merge di tengah. Dengan konfigurasi ini, menyelesaikan conflict menjadi visual, bukan membabi-buta membaca <<<<<<< dan >>>>>>> di file mentah.

Caution

Selama resolusi conflict di :DiffviewOpen, jangan lupa bahwa hasil merge harus disimpan ke file yang benar. Diffview menampilkan file hasil merge sebagai buffer yang bisa diedit — pastikan kalian menyelesaikan semua marker (<<<<<<<, =======, >>>>>>>) sebelum menutup view, dan verifikasi dengan :diffoff / :DiffviewClose bahwa tidak ada marker tersisa. Git akan menolak commit jika masih ada conflict marker.

Menjelajah Riwayat File dan Log Git

Setelah memahami diff, langkah berikutnya adalah membaca riwayat. Ada tiga cara berbeda untuk menelusuri masa lalu sebuah file — masing-masing menjawab pertanyaan berbeda:

Tiga cara membaca riwayat
1. <leader>gb   → blame 1 baris        : "siapa yang menulis BARIS ini?"
2. <leader>gh   → :DiffviewFileHistory % : "commit apa saja yang MENYENTUH file ini?"
3. :Git log    → fugitive/neogit log   : "cerita lengkap branch ini?"

Skenario klasik di tim production: sebuah baris timeout = 30 di file config tiba-tiba bermasalah. Kalian letakkan kursor di baris tersebut, tekan <leader>gb, dan langsung tahu — a1b2c3d — John Doe — 2026-07-12 — fix: raise api timeout. Jika butuh konteks lebih luas, buka :DiffviewFileHistory % untuk melihat serangkaian commit yang menyentuh file, atau gunakan :Git log -- <file> untuk daftar commit-nya. Dari posisi di riwayat, tekan Enter pada diffview untuk membuka diff lengkap commit tersebut. Seluruh investigasi berlangsung tanpa berpindah aplikasi.

Note

Di dalam panel diffview, navigasi antar hunk dan file juga memakai keymap Vim yang sudah kalian kenal: ]c / [c untuk berpindah antar hunk dalam diff (ini keymap bawaan Vim untuk change navigation, bukan konflik dengan [h/]h milik gitsigns — keduanya hidup di buffer berbeda). Gunakan :DiffviewToggleFiles untuk melihat daftar file yang berubah, lalu Enter untuk melompat ke file tersebut dalam diff.

Git Client Bawaan: neogit vs fugitive

Untuk operasi Git yang lebih besar (commit, branch, log, push), kita butuh sebuah git client. Dua opsi paling populer:

Neogit — TUI git client gaya Magit (dari Emacs), dengan antarmuka berpanel yang menampilkan status, diff, log, dan staging dalam satu window:

lua/plugins/neogit.lua
return {
  {
    "NeogitOrg/neogit",
    dependencies = {
      "nvim-lua/plenary.nvim",
      "sindrets/diffview.nvim",
    },
    keys = {
      { "<leader>gg", "<cmd>Neogit<CR>", desc = "Buka Neogit" },
      { "<leader>gc", "<cmd>Neogit commit<CR>", desc = "Commit" },
    },
  },
}

Di dalam Neogit: s untuk stage file/hunk, c untuk commit, p untuk push, l untuk log, ? untuk daftar keymap lengkap.

Fugitive — plugin legendaris karya Tim Pope yang memakai command Ex (:Git), paling populer di ekosistem Vim/Neovim. Keymap dasar yang perlu dihapal:

Fugitive - command dasar
:Git status
:Git commit
:Git log
:Gdiffsplit    " diff file aktif vs index
:Gblame        " blame visual per baris

Note

Memilih antara neogit dan fugitive soal selera: fugitive terasa "Vim-native" (command Ex, jarang perlu mouse), sedangkan neogit terasa seperti GUI Git karena menampilkan daftar status dengan panel navigasi. Banyak developer memakai keduanya: fugitive untuk operasi cepat, neogit untuk menjelajah status secara visual. Kalian juga bisa mulai dengan keduanya — konfigurasi di atas tidak saling mengganggu.

Tabel Ringkasan Keymap Git

ShortcutAksiPlugin
<leader>gsStage hunkgitsigns
<leader>grReset hunk (batalkan)gitsigns
<leader>gpPreview hunkgitsigns
<leader>gSStage seluruh buffergitsigns
<leader>guUndo stage hunkgitsigns
<leader>gbInline blame baris kursorgitsigns
[h / ]hHunk sebelumnya / berikutnyagitsigns
<leader>gdBuka diff viewdiffview
<leader>ghRiwayat filediffview
<leader>ggBuka Neogitneogit
<leader>gcBuka panel commitneogit

Kesalahan Umum Seputar Integrasi Git

KesalahanGejalaSolusi
Blame tidak keluar<leader>gb tidak menampilkan apa-apaBlame butuh baris aktif — pastikan kursor berada di baris yang memang punya perubahan atau kode
Gutter kosongTidak ada tanda +/~ padahal file berubahPastikan buffer punya file yang benar-benar di-track Git; cek git status; coba buka ulang buffer
Merge conflict membingungkanBanyak <<<<<<< tanpa petunjukGunakan :DiffviewOpen saat conflict dan layout diff3_mixed untuk melihat BASE/ours/theirs
Neogit tidak terbukaError git tidak ditemukanInstall Git di sistem (sudo apt install git); neogit butuh binary git di PATH
Diffview menampilkan file salahPerbandingan tidak sesuai harapanPahami argumen: :DiffviewOpen <range>; tanpa argumen, ia membandingkan dengan HEAD
Stage hunk menghilangkan perubahanPerubahan hilang setelah resetreset_hunk menghapus perubahan secara permanen — pastikan hunk yang direset memang ingin dibuang, atau lakukan undo (u) jika langsung menyesal
Undo tidak bisa mengembalikan hunku tidak mengembalikan fileReset hunk menulis ulang buffer; jika undofile (episode 7) aktif, undo Vim bisa menyelamatkan — selalu aktifkan
Diff line highlight anehWarna diff tidak jelasAktifkan enhanced_diff_hl = true di diffview (sudah di config kita)
Performance menurun di repo besarGutter terasa lambat di file raksasaBatasi scope gitsigns (diff_opts) atau matikan untuk buffer tertentu yang sangat besar

Warning

Kesalahan yang paling berbahaya dan paling sering terjadi: menekan <leader>gr (reset hunk) pada baris yang tidak dimaksudkan. Reset hunk tidak memiliki tombol konfirmasi — perubahan langsung hilang. Selalu preview dengan <leader>gp terlebih dahulu untuk memastikan hunk yang benar, dan pastikan undofile aktif (konfigurasi episode 7) sebagai jaring pengaman terakhir.

Penutup

Pada episode 18 ini kita telah menghadirkan Git sepenuhnya ke dalam Neovim: gitsigns.nvim dengan indikator tambah/ubah/hapus di gutter, workflow stage-preview-reset hunk, inline blame, hingga navigasi hunk ([h, ]h). Kita juga menguasai diffview.nvim untuk diff antar branch dan resolusi merge conflict dengan layout diff3_mixed, plus dua pilihan git client — neogit dengan UI berpanel dan fugitive dengan command Ex.

Dengan ini, kalian telah menyelesaikan Fase 4: MODERN IDE CAPABILITIES. Neovim kalian sekarang bukan sekadar editor teks — ia memahami kode secara grammar (Treesitter), semantik (LSP), melengkapi secara kontekstual (nvim-cmp), menjaga konsistensi (conform & nvim-lint), dan hidup berdampingan dengan Git (gitsigns & diffview).

Di episode 19 selanjutnya, kita akan masuk ke Fase 5: Advanced Workflow, Productivity & AI, dimulai dengan Integrated Terminal & Task Management menggunakan toggleterm.nvim — menjalankan terminal, lazygit, dan task runner langsung di dalam Neovim. Perjalanan semakin menarik — pastikan tetap semangat!

Belajar Neovim - Integrasi Git di Dalam Neovim (gitsigns.nvim & diffview.nvim) | Belajar Neovim