ybbond

My site. The main domain
Log | Files | Refs | README | LICENSE | CC-LICENSE

index.md (3322B)


      1 ---
      2 title: Remove Specific Files from Old Git Commit
      3 author: Yohanes Bandung Bondowoso
      4 description: "Ever accidentally committed <code>node_modules</code>?
      5 Or want to remove files from a commit 15 before <code>HEAD</code>?
      6 I did. I'd like to share the solution for you."
      7 tags:
      8   - git #git
      9   - tutorial #tutorial
     10 date: 2020-05-16T13:01:19+0700
     11 image:
     12   src: 1.png
     13 ID: 1589608880
     14 ---
     15 
     16 tldr; [Skip to solution ยป](#how-tos)
     17 
     18 Last week, I encountered a merge conflict while trying to sync my git working branch to latest remote `master`. Merge conflicts is not a serious problem to me, I am used to resolving conflicts. But the conflict that I encountered is from an auto generated typings file from `Apollo Codegen`[^1].
     19 
     20 `Apollo Codegen` file is `Flow` or `TypeScript` typings for the schema and queries in project that uses GraphQL. The generated file often has >10k lines of code. Trying to resolve conflict in that file will make the text editor unresponsive (even with Vim!).
     21 
     22 So I aborted the sync master (`git rebase --abort`), then attempt to remove the changes for the auto-generated codegen file [using lazygit](#lazygit-way). Afterwards, I do sync remote `master` branch and the conflict don't happen. Last thing I do is regenerate the codegen file before posting a Pull Request.
     23 
     24 ## How-Tos
     25 
     26 Back to the post's main topic, to remove specific file using plain old shell command.
     27 
     28 First, checkout to **temporary branch** with the afore mentioned commit as `HEAD` using the commit's hash:
     29 
     30 ```bash
     31 git checkout <commit-hash>
     32 ```
     33 
     34 Then do a **soft reset** to uncommit with all files in staged status:
     35 
     36 ```bash
     37 git reset --soft HEAD^
     38 ```
     39 
     40 Make the desired file(s) unstaged using **reset** command, and then commit with `-c ORIG_HEAD` flag to use the previous commit message. The `--no-edit` flag is optional.
     41 
     42 ```bash
     43 git reset <path/to/file>
     44 ```
     45 ```bash
     46 git commit -c ORIG_HEAD --no-edit
     47 ```
     48 
     49 Discard the changes of the file you want to remove from unstaged area:
     50 
     51 ```bash
     52 git checkout -- .
     53 ```
     54 
     55 Last, `rebase` this **temporary branch** to your branch, from the commit of `<commit-hash>`.
     56 
     57 ```bash
     58 git rebase --onto HEAD <commit-hash> <destination-branch-name>
     59 ```
     60 
     61 If you do this for already merged Pull Request, you need to `push <remote> <branch> --force`. Mind you, doing this will be inconvenient for other people working on same project.
     62 
     63 ## Lazygit Way
     64 
     65 As I mentioned above, I use [lazygit](https://github.com/jesseduffield/lazygit). The process is more straight forward. For the following example, I accidentally committed build file, far before I `.gitignore`d `build/` folder. What I do is:
     66 
     67 ![Navigate to desired commit](1.png)
     68 
     69 ![Press return key, and navigate to file to be removed](2.png)
     70 
     71 ![Press `x` will prompt command list. Turns out `d` will discard the file](3.png)
     72 
     73 ![After pressing `d`, the `Index.js` file is now removed!](4.png)
     74 
     75 Do this way if you want to install lazygit before doing your intention.
     76 
     77 `lazygit` way is easier. I also use [tig](https://github.com/jonas/tig) as a TUI for `git`, but I don't know the command to do the steps wit `tig`.
     78 
     79 [^1]: Here is `Apollo Codegen` [Github](https://github.com/apollographql/apollo-tooling#apollo-clientcodegen-output) page. As a frontend engineer, I consider `codegen` as breakthrough because I can easily type the endpoint's return value.