The story of the webOS Chromium contribution over the past year

In this article, I share how I started webOS Chromium upstream, what webOS patches were contributed by LG Electronics, and how I’ve contributed to Chromium.

First, let’s briefly describe the history of the webOS. WebOS was created by Palm, Inc. Palm Inc. was acquired by HP in 2010 and HP made the platform open source, so it then became open webOS. In January 2014 the operation system was sold to LG Electronics. LG Electronics has been shipping the webOS for their TV and signage products since. LG Electronics has also been spreading the webOS to more of their products.

The webOS uses Chromium to run web applications. So, Chromium is a very important component in the webOS. As other Chromium embedders, the webOS also has many downstream patches. So, LG Electronics has tried to contribute own downstream patches to the Chromium open source project to reduce the effort to catch up to the latest Chromium version as well as to improve the quality of the downstream patches. As one of LG Electronics contractors for the last one and half years, I’ve started to work on the webOS Chromium contribution since September 2017. So, let’s start to explain the process of contributing:

1. The Corporate CLA

The Chromium project only accepts patches after the contributor signs a Contributor License Agreement (CLA). There are two kinds of CLA, one for individual and one corporate contributors. If a company signs the corporate CLA, then the individual contributors are exempt from signing an individual CLA, however, they must use their corporate email address as well as join the google group which was created when the corporate CLA was signed. LG Electronics signed up the corporate CLA and they were added to AUTHOR file.

  • Corporate Contributor License Agreement (Link)

  • Individual Contributor License Agreement (Link)

2. List upstreamable patches in webOS

After finishing the registration of the corporate CLA, I started to list up upstreamable webOS patches. It seemed to me that there were two categories in the patches. One was new features for the webOS. The other one was bug fixes. In the case of new features, the patches were mainly to improve the performance or to make LG products like TV and signage use less memory. I tried to list upstreamable patches among those patches. The patch criteria was either to improve the performance or obtain a benefit on the desktop. I thought this would allow owners to accept and merge the patch into the mainline more easily.

3. What patches have been merged to Chromium mainline?

Before uploading webOS patches, I merged the patches to replace deprecated WTF or base utilities (WTF::RefPtr, base::MakeUnique) with c++ standard things. I thought that it would be good to show that LG Electronics started to contribute to Chromium. After replacing all of them, I could start to contribute webOS patches in earnest. I’ve since merged webOS patches to reduce memory usage, release more used memory under OOM, add a new content API to suspend/resume DOM operation, and so on. Below is the list of the main patches I successfully merged.

  1. New content API to suspend/resume DOM operation
  2. Release more used memory under an out-of-memory situation
  3. Introduce new command line switches for embedded devices

4. Trace LG Electronics contribution stats

As more webOS patches have been merged to Chromium mainline, I thought that it would be good if we run a tool to chase all LG Electronics Chromium contributions so that LG Electronics’s Chromium contribution efforts are well documented. To do this I set up the LG Electronics Chromium contribution stats using the GitStats tool. The tool has been generating the stats every day.

I was happy to work on the webOS upstream project over the past year. It was challenging work because the downstream patch should show some benefits in Chromium mainline. I’m sure that LG Electronics will continue to keep contributing good patches to webOS and I hope they’re going to become a good partner as well as a contributor in Chromium.

Posted in Igalia-Chromium | Leave a comment

How to develop Chromium with Visual Studio Code on Linux?

How have you been developing Chromium? I have often been asked what is the best tool to develop Chromium. I guess Chromium developers have been usually using vim, emacs, cscope, sublime text, eclipse, etc. And they have used GDB or console logs for debugging. But, in case of Windows, developers have used Visual Studio. Although Visual Studio supports powerful features to develop C/C++ programs, unfortunately, it couldn’t be used by other platform developers. However, recently I notice that Visual Studio Code also can support to develop Chromium with the nice editor, powerful debugging tools, and a lot of extensions. And, even it can work on Linux and Mac because it is based on Electron. Nowadays I’m developing Chromium with VS Code. I feel that VS Code is one of the very nice tools to develop Chromium. So I’d like to share my experience how to develop Chromium by using the Visual Studio Code on Ubuntu.

Default settings for Chromium

There is already an article about how to set up the environment to build Chromium in VS codeSo to start, you need to prepare the environment settings. This section just lists key points in the instructions.
* https://chromium.googlesource.com/chromium/src/+/lkcr/docs/vscode.md

  1. Download VS Code
    https://code.visualstudio.com/docs/setup/setup-overview
  2. Launch VS Code in chromium/src
    $ code .
  3. Install useful extensions
    1. Python – Linting, intellisense, code formatting, refactoring, debugging, snippets.
    2. c/c++ for visual studio code – Code formatting, debugging, Intellisense.
    3.  Toggle Header/Source Toggles between .cc and .h with F4. The C/C++ extension supports this as well through Alt+O but sometimes chooses the wrong file when there are multiple files in the workspace that have the same name.
    4. you-complete-me YouCompleteMe code completion for VS Code. It works fairly well in Chromium. To install You-Complete-Me, enter these commands in a terminal:
      $ git clone https://github.com/Valloric/ycmd.git ~/.ycmd 
      $ cd ~/.ycmd 
      $ git submodule update --init --recursive 
      $ ./build.py --clang-completer
    5. Rewrap –  Wrap lines at 80 characters with Alt+Q.
  4. Setup for Chromium
    1.  Chromium added the default settings files for vscode. We can move them to //src/.vscode folder.
      1. Workspace setting
        https://cs.chromium.org/chromium/src/tools/vscode/settings.json5
      2. Task setting
        https://cs.chromium.org/chromium/src/tools/vscode/tasks.json5
      3. Launch setting
        – https://cs.chromium.org/chromium/src/tools/vscode/launch.json5
  5. Key mapping
    * Ctrl+P: opens a search box to find and open a file.
    * F1 or Ctrl+Shift+P: opens a search box to find a command
      (e.g. Tasks: Run Task).
    * Ctrl+K, Ctrl+S: opens the key bindings editor.
    * Ctrl+`: toggles the built-in terminal.
    * Ctrl+Shift+M: toggles the problems view (linter warnings, 
      compile errors and warnings). You'll swicth a lot between
      terminal and problem view during compilation.
    * Alt+O: switches between the source/header file.
    * Ctrl+G: jumps to a line.
    * F12: jumps to the definition of the symbol at the cursor
      (also available on right-click context menu).
    * Shift+F12 or F1: CodeSearchReferences, Return shows all
      references of the symbol at the cursor.
    * F1: CodeSearchOpen, Return opens the current file in
      Code Search.
    * Ctrl+D: selects the word at the cursor. Pressing it multiple
      times multi-selects the next occurrences, so typing in one
      types in all of them, and Ctrl+U deselects the last occurrence.
    * Ctrl+K+Z: enters Zen Mode, a fullscreen editing mode with
      nothing but the current editor visible.
    * Ctrl+X: without anything selected cuts the current line.
      Ctrl+V pastes the line.
  6. (Optional) Color setting
    • Press Ctrl+Shift+P, color, Enter to pick a color scheme for the editor

Additional settings after the default settings.

  1. Set workspaceRoot to .bashrc. (Because it will be needed for some extensions.)
    export workspaceRoot=$HOME/chromium/src
  2. Copy 3 settings files from //src/tools/vscode to //src/.vscode
    • $ mkdir .vscode/
      $ cp tools/vscode/settings.json5 .vscode/settings.json
      $ cp tools/vscode/tasks.json5 .vscode/tasks.json
      $ cp tools/vscode/launch.json5 .vscode/launch.json
    • You can find my configuration files based on the default files
      1. https://github.com/Gyuyoung/vscode
  3. Set ycmd path to .vscode/settings.json
    • // YouCompleteMe
      "ycmd.path": "<path>/.ycmd", // Please replace this path
  4. Add new tasks to tasks.json in order to build Chromium by using ICECC.
{
  "taskName": "1-build_chrome_debug_icecc",
  "command": "buildChromiumICECC.sh Debug",
  "isShellCommand": true,
  "isTestCommand": true,
  "problemMatcher": [
    {
      "owner": "cpp",
      "fileLocation": [
        "relative",
        "${workspaceRoot}"
      ],
      "pattern": {
        "regexp": "^../../(.*):(\\d+):(\\d+):\\s+(warning|\\w*\\s?error):\\s+(.*)$",
        "file": 1,
        "line": 2,
        "column": 3,
        "severity": 4,
        "message": 5
      }
    },
    {
      "owner": "cpp",
      "fileLocation": [
        "relative",
        "${workspaceRoot}"
      ],
      "pattern": {
        "regexp": "^../../(.*?):(.*):\\s+(warning|\\w*\\s?error):\\s+(.*)$",
        "file": 1,
        "severity": 3,
        "message": 4
      }
    }
  ]
},
  1. Update “Chrome Debug” configuration in launch.json
{
  "name": "Chrome Debug",
  "type": "cppdbg",
  "request": "launch",
  "targetArchitecture": "x64",
  "environment": [
    {"name":"workspaceRoot", "value":"${HOME}/chromium/src"}
  ],
  "program": "${workspaceRoot}/out/Debug/chrome",
  "args": ["--single-process"],  // The debugger only can work with the single process mode for now.
  "preLaunchTask": "1-build_chrome_debug_icecc",
  "stopAtEntry": false,
  "cwd": "${workspaceRoot}/out/Debug",
  "externalConsole": true,
},

Screenshot after the settings

you will see this window after finishing all settings.

Build Chromium with ICECC in VS Code

  1. Run Task (Menu -> Terminal -> Run Tasks…)
  2. Select 1-build_chrome_debug_icecc. VS Code will show an integrated terminal when building Chromium as below, On the ICECC monitor, you can see that VS Code builds Chromium by using ICECC.

 

Start debugging in VS Code

After completing the build, now is time to start debugging Chromium.

  1. Set a breakpoint
    1. F9 button or just click the left side of line number
  2. Launch debug
    1. Press F5 button
  3. Screen captures when debugger stopped at a breakpoint
    1. Overview
    2. Editor
    3. Call stack
    4. Variables
    5. Watch
    6. Breakpoints

Todo

In multiple processes model, VS Code can’t debug child processes yet (i.e. renderer process). According to C/C++ extension project site, they suggested us to add the below command to launch.json though, it didn’t work for Chromium when I tried.

"setupCommands": [
    { "text": "-gdb-set follow-fork-mode child" }
],

Reference

  1. Chromium VS Code setup: https://chromium.googlesource.com/chromium/src/+/lkcr/docs/vscode.md
  2. https://github.com/Microsoft/vscode-cpptools/blob/master/launch.md
Posted in Igalia-Chromium | Tagged , | 4 Comments

Share my experience to build Chromium with ICECC and Jumbo

If you’re a Chromium developer, I guess that you’ve suffered from the long build time of Chromium like me. Recently, I’ve set up the icecc build environment for Chromium in the Igalia Korea office. Although there have been some instructions how to build Chromium with ICECC, I think that someone might feel they are a bit difficult. So, I’d like to share my experience how to set up the environment to build Chromium on the icecc with Clang on Linux in order to speed up the build of Chromium.

P.S. Recently Google announced that they will open Goma (Google internal distributed build system) for everyone. Let’s see goma can make us not to use icecc anymore 😉
https://groups.google.com/a/chromium.org/forum/?utm_medium=email&utm_source=footer#!msg/chromium-dev/q7hSGr_JNzg/p44IkGhDDgAJ

Prerequisites in your environment

  1. First, we should install the icecc on your all machines.
    sudo apt-get install icecc ccache [icecc-monitor]
  2. To build Chromium using icecc on the Clang, we have to use some configurations when generating the gn files. To do it as easily as possible, I made a script. So you just download it and register it to $PATH. 
    1. Clone the script project
      $ git clone https://github.com/Gyuyoung/ChromiumBuild.git

      FYI, you can see the detailed configuration here – https://github.com/Gyuyoung/ChromiumBuild/blob/master/buildChromiumICECC.sh

    2. Add your chromium/src path to buildChromiumICECC.sh
      # Please set your path to ICECC_VERSION and CHROMIUM_SRC.
      export CHROMIUM_SRC=$HOME/chromium/src
      export ICECC_VERSION=$HOME/chromium/clang.tar.gz
    3. Register it to PATH environment in .bashrc
      export PATH=/path/to/ChromiumBuild:$PATH
    4. Link Clang to icecream so that Clang gets redirected trough Icecream
      $ cd /usr/lib/icecc/bin
      $ sudo ln -s /usr/bin/icecc ./clang
      $ sudo ln -s /usr/bin/icecc ./clang++
    5. Add the patched Chromium version of the Clang executable to your PATH right after Icecream
      $ export PATH="/usr/lib/icecc/bin:$HOME/chromium/src/third_party/llvm-build/Release+Asserts/bin/:$PATH"
    6. Create a clang toolchain from the patched Chromium version
      I added the process to “sync” argument of buildChromiumICECC.sh. So please just execute the below command before starting compiling. Whenever you run it, clang.tar.gz will be updated every time with the latest Chromium version.

      $ buildChromiumICECC.sh sync

Build

  1. Run an icecc scheduler on a master machine,
    sudo service icecc-scheduler start
  2. Then, run an icecc daemon on each slave machine
    sudo service iceccd start

    If you run icemon, you can monitor the build status on the icecc.

  3. Start building in chromium/src
    $ buildChromiumICECC.sh Debug|Release

    When you start building Chromium, you’ll see that the icecc works on the monitor!

Build Time

In my case, I’ve  been using 1 laptop and 2 desktops for Chromium build. The HW information is as below,

  • Laptop (Dell XPS 15″ 9560)
    1. CPU: Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz
    2. RAM: 16G
    3. SSD
  • Desktop 1
    1. CPU: Intel(R) Core(TM) i7-4790K CPU @ 4.00GHz
    2. RAM: 16G
    3. SSD
  • Desktop 2
    1. CPU: Intel(R) Core(TM) i7-4790K CPU @ 4.00GHz
    2. RAM: 16G
    3. SSD

I’ve measured how long time I’ve spent to build Chromium with the script in below cases,

  • Laptop
    • Build time on Release with the jumbo build: About 84 min
    • Build time on Release without the jumbo build: About 203 min
  • Laptop + Desktop 1 + Desktop 2
    • Build time on Release with the jumbo build: About 35 min
    • Build time on Release without the jumbo build: About 73 min

But these builds haven’t applied any object caching by ccache yet. If ccache works next time, the build time will be reduced. Besides, the build time is depended on the count of build nodes and performance. So this time can differ from your environment.

Troubleshooting

  1. Undeclared identifier
    1. Error message
      /home/gyuyoung/chromium/src/third_party/llvm-build/Release+Asserts
       /lib/clang/6.0.0/include/avx512vnniintrin.h:38:20:
       error: use of undeclared identifier '__builtin_ia32_vpdpbusd512_mask'
       return (__m512i) __builtin_ia32_vpdpbusd512_mask ((__v16si) __S, ^
    2. Solution
      Restart to icecc-scheduler and all icecc nodes.
  2. Out of Memory
    1. Error message
      LLVM ERROR: out of memory
    2. Solution
      • Add more physical RAM to the machine.
      • Alternatively, we can try to increase the space of swap. (But, this may not solve the OOM issue. In such a case, we should increase the physical RAM)
        • For example, create a 4G swap file
          $ size="4G" && file_swap=/swapfile_$size.img && sudo touch $file_swap && sudo fallocate -l $size /$file_swap && sudo mkswap /$file_swap && sudo swapon -p 20 /$file_swap
          

        • Make the swap file permanent
          # in your /etc/fstab file
          /swapfile    none    swap    sw,pri=10      0       0
          /swapfile_4G.img     none    swap    sw,pri=20      0       0
        • Check swap situation after reboot
          $ sudo swapon  -s
          Filename       Type     Size        Used    Priority
          /swapfile      file     262140      0       10
          /swapfile_4G.img       file     4194300     0       20

Reference

  1. WebKitGTK SpeedUpBuild: https://trac.webkit.org/wiki/WebKitGTK/SpeedUpBuild
  2. compiling-chromium-with-clang-and-icecc : http://mkollaro.github.io/2015/05/08/compiling-chromium-with-clang-and-icecc/
  3. Rune Lillesveen’s icecc-chromium project:
    https://github.com/lilles/icecc-chromium
  4. How to increase swap space?
    https://askubuntu.com/questions/178712/how-to-increase-swap-space
Posted in Igalia-Chromium | Tagged , , , | 6 Comments

What is navigator.registerProtocolHandler?

UPDATE: I made a presentation at the lightning session of BlinkOn9 Sunnyvale.

Have you heard that navigator.registerProtocolHandler javascript API?

The API is to give you the power to add your customized scheme(a.k.a. protocol) to your website or web application. If you register your own custom scheme, it can help you to avoid collisions with other DNS, or help other people use it correctly, and be able to claim the moral high ground if they use it incorrectly. In this post, I would like to introduce the feature with some examples, and what I’ve contributed to the feature.

Introduction

The registerProtocolHandler had been started discussing since 2006. Finally, it was introduced in HTML5 for the first time.

This is a simple example of the use of navigator.registerProtocolHandler. Basically, the registerProtocolHandler takes three arguments,

  • scheme – The scheme that you want to handle. For example, mailto, tel, bitcoin, or irc.
  • url – A URL within your web application that can handle the specified scheme.
  • title – The title of the handler.
<script>
     navigator.registerProtocolHandler("web+search",
                                       "https://www.example/search/url=%s",
                                       "web search");
</script>
<a href="web+search:igalia">Igalia</a>

As this example, you can register a custom scheme with a URL that can be combined with the given URL(web+search:igalia)

However, you need to keep in mind some limitations when you use it.

  1. URL should include %s placeholder.
  2. You can register own custom handler only when the URL of the custom handler is same the website origin. If not, the browser will generate a security error.
  3. There are pre-defined schemes in the specification. Except for these schemes, you’re only able to use “web+foo” style scheme. But, the length of “web+foo” is at least five characters including ‘web+’ prefix. If not, the browser will generate a security error.
    • bitcoin, geo, im, irc, ircs, magnet, mailto, mms, news, nntp, openpgp4fpr, sip, sms, smsto, ssh, tel, urn, webcal, wtai, xmpp.
  4. Schemes should not contain any colons. For example, mailto: will generate an error. So, you have to just use mailto.

Status on major browsers

Firefox (3+)

When Firefox meets a webpage which includes navigator.registerProtocolHandler as below,

navigator.registerProtocolHandler("web+search",
                                  "https://www.example/search/url=%s",
                                  "web search");

It will show an alert bar just below the URL bar. Then, it will ask us if we want to add the URL to the Firefox handler list.

After allowing to add it to the supported handler list, you can see it in the Applications section of the settings page (about:preferences#general).

Now, the web+github custom scheme can be used in the site as below,

<a href="web+github:wiki">Wiki</a>
<a href="web+github:Pull requests">PR</a>

Chromium (13+)

Let’s take a look Chrome on the registerProtocolHandler. In Chrome, Chrome shows a new button inside the URL bar instead of the alert bar in Firefox.

If you press the button, a dialog will be shown in order to ask if you allow the website to register the custom scheme.

In the “Handlers” section of the settings (chrome://settings/handlers?search=protocol), you’re able to see that the custom handler was registered.

FYI, other browsers based on Chromium (i.e. Opera, Yandex, Whale, etc.) have handled it similar to Chrome unless each vendor has own specific behavior.

Safari (WebKit)

Though WebKit has supported this feature in WebCore and WebProcess of WebKit2, no browsers based on WebKit have supported this feature with UI. Although I had tried to implement it in UIProcess of WebKit2 through the webkit-dev mailing list so that browsers based on WebKit can support it, Unfortunately, some of Apple engineers had doubts about this feature though there were some agreements to support it in WebKit. So I failed to implement it in UIProcess of WebKit2.

My contributions in WebKit and Chromium

I’ve mainly contributed to apply new changes in the specification, to fix bugs and improve test cases. First, I’d like to introduce the bug that I modified in Chromium recently.

Let’s assume that URL has multiple placeholders(%s).

navigator.registerProtocolHandler("test",
                                  "http://example.com/%s/url=%s",
                                  "title");" 
<a href="test:duplicated_placeholders">this</a>

According to the specification, only first “%s” placeholder should be substituted, not substitute all placeholders. But, Chrome has substituted all placeholders with the given URL as below, even though Firefox has only substituted the first placeholder.

http://example.com/test%3Aduplicated_placeholders/url=test%3Aduplicated_placeholders

So I fixed the problem in [registerProtocolHandler] Only substitute the first “%s” placeholder. The latest Chromium substitutes only first placeholder like below,

http://example.com/test%3Aduplicated_placeholders/url=%s

This is a whole list what I’ve contributed both WebKit and Chromium so far.

  1.  WebKit
  2. Chromium

Summary

So far, we’ve looked at the navigator.registerProtcolHandler for your web application simply. The API can be useful if you want to make users use your web applications like a web-based email client or calendar.

Posted in Igalia-Chromium | Leave a comment

How to make your code on downstream ?

Nowadays most of my projects have been using opensource or worked based on opensource. If we just needs to use it, I think it would be a good situation for you. However we usually have projects that keep the opensource over years for your products. So if you have to hack a lot of modules inside of opensource code, it can be a nightmare when you rebase current source base against the latest opensource after months or years. In this article I would like to share some of my experiences on how to make a downstream patch when we work using opensource.

  1. Try to contribute your patch to the opensource project as much as possible

    • I think this is the best way to reduce our heavy burden that we should maintain in your downstream source code. Even if the opensource project you’re using is being developed fast, you will often face many conflicts during the rebase because it’s likely that original code or architecture have changed frequently in the meantime. To avoid the conflict, it would be best if you contribute your patch to the opensource project as much as possible.
    • Below documents are a good example to explain how to contribute your code to the opensource project.
  2. Make your downstream port

    • We know well that #1 is the best way to reduce our downstream patches though, it is often hard to keep because downstream patches are often too hacky or unstable. Even if you submit a downstream patch to upstream, you might get many review comments or objections from the opensource maintainers. In such case, what else can you do ? In my experience, it was important to separate our downstream implementation from the original code. For example, we can make new TriangleFoo.h/cpp files instead of original Triangle.h/cpp files, then we can use them through the modification of few build scripts.
      1. Figure class
       class Figure {
        public:
            virtual int calculateSize();
       }
       
      2. Triangle class
       class Triangle : public Figure {
        public:
            virtual int calculateSize() override;
       }
      
       Triangle::calculateSize() {
           return width * height / 2;
       }
      
      3. TriangleFoo class
       class TriangleFoo : public Figure {
           public: virtual int calculateSize() override;
       }
       
       TriangleFoo::calculateSize() {
           return new_width * height / 2;
       }
      
      4. Build script. In this example we use cmake,
       list(APPEND Figure_SOURCES
           Figure.cpp
           Triangle.cpp
           TriangleFoo.cpp
       )
       
       list(REMOVE_ITEM Figure_SOURCES
           Triangle.cpp
       )

      We can avoid some conflicts in the next rebase with the latest opensource in the Triangle.h/cpp files. However we still need to modify the TriangleFoo.h/cpp if Figure.h is changed. For example, when a new parameter is added or a return type is changed.

  3. Use #if ~ #endif guard

    • When we only need to modify few lines or just to change logic inside a function, we can use #if ~ #else ~ #endif guard. The guard can help us to know what codes were added by us or modified by us. Besides it might be help us to check easily if the downstream patch generated side effects through turning it off. In my previous projects, most of issues have come from downstream patches because they lacked code review, missed test cases, or were too hacky against original architecture. In such cases, you can check the issue just by turning the guard off. However, if you use #if ~ #endif guard in many places, the usages can mess your code up. So I’d like to recommend you use it only when you really need.
      Triangle::calculateSize()
      {
      #if defined(DOWNSTREAM_ENABLED)
          return new_width * height / 2;
      #else
          return width * height / 2;
      #endif
      }
  4. Try to make a patch per a feature

    • As you may have experienced before, it is very hard to implement a feature with a commit. Even though you succeed in implementing a new feature with a commit perfectly, you may face to touch the implementation again in order to fix a bug or apply new requirements again. In such case your git history will get messier and messier. It will make it difficult to rebase based on the latest opensource. To avoid it, you may have manually merged original implementation with the fixup commits reflected later. But there are two useful git commands for this case – git commit fixup and git rebase –autosquash.
        • git commit –fixup : Automatically marks your commit as a fix of a previous commit. Construct a commit message for use with git rebase –autosquash.
        • git rebase -i –autosquash : Automatically organize merging of these fixup commits and associated normal commits.

    • Example
      There is a good article to explain that explains method [1]. If you need to understand further, it would be good if you visit the URL. Let’s assume that we have 3 commits on your local repository.

      $ git log --oneline
        new commit1 (7ae79f6)
        new commit2 (9e4c1de)
        new commit3 (480ee07)
        previous commit (19c8abf)

      But if we just noticed that we missed to add a comment in commit2, it’s time to use --fixup option.

      $ git add [modified file]
      $ git commit --fixup [new commit2's commit-id]
        (i.e. git commit --fixup 9e4c1de)

      Then you can clean your branch before merging it using - autosquash option.

      $ git rebase -i --autosquash [previous commit id]
        (i.e. git rebase -i autosquash 19c8abf)

 

Reference
[1] http://fle.github.io/git-tip-keep-your-branch-clean-with-fixup-and-autosquash.html

Posted in opensource | Tagged , | Leave a comment