Home Up MPLAB GIT Rebase GIT and CPS Bad Syntax Tortoise


Using the GIT client in MPLAB

The following is adapted from a forum post, and the original post "rambles" quite a bit.

In my view the GIT version built into MPLAB is usable, subject to some limitations such as the line-endings issue. This post is a bit longwinded as I went back and edited it as I learned more but to summarise:

  1. I strongly advise configuring "autocrlf" (described below)
  2. I strongly advise using a gitignore file
  3. If (like me) you commit your MPLAB config files then on checking out a revision you must close and reopen the project as MPLAB does not auto-reload configs (I'll qualify that by saying MPLAB 4.05+ might reload configs after a checkout, unconfirmed)
  4. MPLAB appears to ignore gitattributes
  5. It is definitely worth learning about remotes early, though the language is confusing.
  6. You don't have to use GITHUB or BITBUCKET, a bare repository in a folder will serve as a remote repository, but as GITHUB now allow free-tier accounts to own private repositories there aren't that many reasons not to use an online service.
  7. You may have to "build clean" after checking out a different branch, particularly if files have been removed or renamed. This also applies to reverting to older versions.
  8. You may find that the MPLAB "build clean" function (needed to clear linker errors post-checkout) does not work correctly if you are attempting to build multiple configurations. It will just clean the current active configuration but not the whole list. If you are letting MPLAB batch build all configurations you may need to manually clean each configuration in turn.

If like me you have been keeping your work on a local NAS server then you might consider converting the server copy into a "bare" repository. This means you can do your work on a local clone, which nicely sidesteps MPLAB's inability to use UNC paths. Note that I'm not covering the process here precisely because I didn't learn remotes properly, and I'm just learning it now.

I've been looking at this myself, I think I've been using git in MPLAB for about a year, and I've recently been doing some housekeeping to my projects with a view to pushing them to a server of some sort.

The "server" might end up being headless repos on a Windows share though...

One irritation about "bare" repositories is they appear to still have an "active" branch even though there is no working tree for it to be checked out into. There's an odd procedure to set the active branch, because you can't use check-out.

General git tip: "git branch -vv" (git branch --verbose --verbose) will list branches and their connection to the remote. This should be easier.

I'm trying to establish what version of GIT MPLAB uses, and the information indicates that it may be the Java "JGIT" rather than GIT, and further that the GIT plugin may be extremely old? My main issue is it uses an out of date strategy for handling line-endings.

Probably the single biggest problem I have found so far is that if you use "Check out" in MPLAB it does not currently "flush" and reload the configuration files. The changes made by Check-out can even hang the IDE. When winding back to earlier versions this makes it retain bits of newer version configurations such as source file names that don't exist yet. It seems as if you must close the project and check out with an external git such as git_gui to get configurations to reload properly, or maybe you can check out and immediately quit MPLAB before it has time to re-save the config?

Checking out lesser revisions that don't change configuration will work fine though.

The other problem is line endings, this is covered elsewhere but GIT is first and foremost a Linux tool and you are expected to use Linux line endings. Regular GIT has a configuration file: .gitattributes that tells it how to handle various file formats. Without gitattributes it tries to infer how to handle a file from its contents. Git leans heavily towards converting text files unless conversion is deliberately disabled.

JGIT (MPLAB) seems to use a more conservative strategy for line endings, it doesn't support gitattributes and the conversion rules appear inconsistent.

By default a MPLAB X install appears to have "core.autocrlf" not set at all, which seems to mean it may still convert LF to CRLF on checkout (unconfirmed), but doesn't convert CRLF to LF on check in. For consistency with external GIT you really need to set auto-crlf to something for the repository as otherwise an external "git" will default to its global or system setting which is almost always different to the default used by MPLAB. Enable it by "git config --local core.autocrlf true" or by editing the configuration in MPLAB, and adding the "    autocrlf = true" entry at the end of "[core]" just before "[gui]". I'm reluctant to directly edit the config file but that's how MPLAB presents it.

I've tried this on a fresh repository prior to the first commit and it appears to have worked. At this time I have not added a gitattributes file.

Note that if you have a Windows-only environment and actually want to commit in Windows CRLF format then just set autocrlf false and don't set a .gitattributes file at all. This way MPLAB X GIT and external GIT should both add files as-is and should at least be consistent, letting you use an external GIT for maintenance tasks.

With the right prodding MPLAB GIT can produce correct LF-ended text commits, and can coexist with regular GIT. It will also accept files that are LF-ended already, though regular GIT will warn about adding a LF-ended file if the default is to check it out as CRLF-ended.

The only remaining oddity is occasional phantom changes, which can be cleared by a hard reset to HEAD once it is confirmed that no real edits will be lost.

Also MCC is fond of reordering includes, which leads to trivial changes. I'm allowing them through at present but it might be worth reverting swaps to simplify the history.

If you have been using MPLAB X GIT unconfigured for a while you probably have a lot of CRLF commits. There is a procedure to correct these using "git filter-branch" but it is complicated and I would advise finding good instructions elsewhere. I copied someone else's procedure so I won't pretend to explain the process. I'd strongly advise doing it though, the advantage of a correct configuration is not having unexpected whole-file diffs and merge conflicts whenever a file's format changes.

It is best to avoid using filter-branch on a repository that has remotes, as the outcome of a filter will not push to the remote cleanly. To push it you will have to select "force", and the resulting forced update can cause problems, however if you DO find yourself in that position there are ways to fix it:

  1. If it is your branch that needs cleaning and nothing else depends on it then just filter/rebase and push it using "force" before anyone else checks it out. This works well if you find you've made a small run of CRLF commits on an otherwise LF-ended repository, or otherwise goofed in a way that needs purging from the git history.
  2. For a solo or small team project just make sure all your repository clones are "clean", e.g. all commits pushed to the remote before you rebase, then push the rebased branches using the "force" option, and remember to fetch before you work.
  3. If you do the above and find that you missed a clone and you have some commits that are on the old branch there's a variant of the rebase command that will fix it
  4. You could run the same filter-branch command on the clone, it SHOULD bring it into line, though this depends on the filter producing exactly the same output when run a second time on a different machine.

To verify what style of line-ending is in a file in "HEAD" using the "git bash" shell you can type:

git show HEAD:<file> | file -
where <file> is the filename. "git show" will bypass the filter and tell you what was actually stored. This also works for branches and history, just substitute the branch for "HEAD".

There are other ways based on using a pattern-match tool to look for "\r\n" but I like the "show" method.