Skip to content

miscellaneous

Manlio Morini edited this page Jan 3, 2018 · 26 revisions

Git related

How to find the changeset that introduced a bug

It often happens that you realize that something is broken and that it has been broken for a while. With git bisect, you can figure out exactly when it became broken. When you know that, it is often much easier to fix the problem.

It works like this. You start by marking the current revision as bad since it contains the bug:

$ git bisect bad
You need to start by "git bisect start"
Do you want me to do it for you [Y/n]? y

You then jump back in history to a point where you hope the bug is not present:

$ git checkout HEAD~100
Note: checking out 'HEAD~100'.

You have to test your software at this revision and if the bug is not present, then you can mark it as good:

$ make tests
...
$ git bisect good
Bisecting: 675 revisions left to test after this (roughly 10 steps)

If HEAD~100 is known to be good you can directly issue the command git bisect good HEAD~100.

When you marked it as good, Git updated your working copy to a place roughly in the middle between the good and bad changesets. You now have to test this changeset and mark it good/bad.

$ make tests
...
$ git bisect good
Bisecting: 337 revisions left to test after this (roughly 9 steps)

Continue like this until Git has narrowed the search down to a single changeset.

You still have to do the debugging yourself, but using git bisect saves you from keeping track of which changesets you have already tested and which you still need to test.

When you're finished using the git bisect command in a repository, you can use the git bisect reset command to drop the information it was using to drive your search.

(as a reference the same procedure is described by Martin Geisler on Stackoverflow for hg)

View the change history of a file

Use

gitk filename

or, to follow filename past renames:

gitk --follow filename

Since gitk isn't part of the basic git package, you can also consider:

git log -p filename

The -p option let git generate the patches for each log entry.

Git equivalents of most common Mercurial commands

Since the project was once stored in a Mercurial repository, some developers may find useful a git-hg Rosetta stone:

  • hg clone -> git clone
  • hg diff ->
    • git diff shows unstaged changes
    • git diff --cached shows staged changes
    • git diff HEAD shows all changes (both staged and unstaged) git diff HEAD
  • hg diff -r A:B -> hg diff A B
  • hg status -> git status
  • hg manifest -> git ls-tree -r --name-only --full-tree HEAD
  • hg commit -> git add ; git commit or git commit -a
  • hg view -> gitk and git gui
  • hg log -> git log
  • hg add -> git add
  • hg push -> git push
  • hg pull ; hg update -> git pull
  • hg update tip -> git checkout HEAD
  • hg merge -> git merge
  • hg revert filename -> git checkout filename (git checkout -- . for everything in the current directory)
  • hg backout -> git revert
  • hg rollback -> git reset --soft HEAD^. With git you may actually prefer to use --amend, e.g.:
    • git commit "Fixed #123"
    • remembered that I forgot to do something
    • do something
    • git commit --amend and edit the notes
  • hg rm / hg mv -> git rm / git mv
  • hg addremove -> git add -A
  • .hgrc -> .gitconfig
  • .hgignore -> .gitignore

Emacs related

Using ediff as git mergetool

Add the following sections to the .gitconfig file (code from https://stackoverflow.com/a/1818855/3235496):

[merge]
    tool = ediff
[mergetool.ediff]
# See https://stackoverflow.com/a/1818855/3235496
    cmd = emacs --eval \"\
(progn\
  (defun ediff-write-merge-buffer ()\
    (let ((file ediff-merge-store-file))\
      (set-buffer ediff-buffer-C)\
      (write-region (point-min) (point-max) file)\
      (message \\\"Merge buffer saved in: %s\\\" file)\
      (set-buffer-modified-p nil)\
      (sit-for 1)))\
  (setq ediff-quit-hook 'kill-emacs\
        ediff-quit-merge-hook 'ediff-write-merge-buffer)\
  (ediff-merge-files-with-ancestor \\\"$LOCAL\\\" \\\"$REMOTE\\\"\
                                   \\\"$BASE\\\" nil \\\"$MERGED\\\"))\"

Now using the git mergetool command Emacs will be used (just edit the conflicting merge, save and exit to proceed to the next one).

Convert Dos to Unix line terminator via Emacs

Since many Vita-developers use Emacs and we prefer the Unix line terminator (\n), a useful command to remember is:

M-x set-buffer-file-coding-system RET iso-8859-15-unix

(undecided-unix is another valid option)

and now save the file with its new buffer coding system:

C-x C-s

Other areas

How to use static analysis tools

Cppcheck

Cppcheck is a static analysis tool for C/C++ code. Unlike C/C++ compilers and many other analysis tools it does not detect syntax errors in the code. Cppcheck primarily detects the types of bugs that the compilers normally do not detect.

$ make check_cppcheck 2>&1 | less

Cpplint

Cpplint is a checker to make sure a C++ file follows Google's C++ style guide.

$ make check_cpplint 2>&1 | less

Note that we follow just a few of Google's recommendations.

Debug vs Release in CMAKE

It's generally best to do an out of source build. From the vita/src directory:

$ mkdir release
$ cd release
$ cmake -DCMAKE_BUILD_TYPE=Release ..
$ make

and for Debug:

$ mkdir debug
$ cd debug
$ cmake -DCMAKE_BUILD_TYPE=Debug ..
$ make
You can’t perform that action at this time.