MPLAB GIT
Home Up MPLAB GIT Rebase GM Studio Git GIT and CPS Bad Syntax Tortoise

 

Using the GIT client in Microchip MPLAB X

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) unless you are using Linux
  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 configuration files 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. This may have been fixed by version 5.45?

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 (only in Windows). Note that I'm not covering the process here precisely because I didn't learn remotes properly, and I'm just learning it now so its probably better to look it up elsewhere.

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" (that's "v" twice not a W) or "git branch --verbose --verbose" will list branches and their connection to the remote in detail. 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 checking out a different branch 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 only contain code edits and 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 that in Windows 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.

Setting the CRLF option from GIT GUI

Running the following adds three commands to the GIT GUI "tools" menu to set the local (repository) crlf option.

git config --global --add guitool."Set autocrlf true".cmd "git config --local core.autocrlf true"
git config --global --add guitool."Set autocrlf false".cmd "git config --local core.autocrlf false"
git config --global --add guitool."Set autocrlf input".cmd "git config --local core.autocrlf input"

While the syntax is a bit rough it is possible to use "git config" to add options to Git GUI, which enables the options to be packaged into a short script. The above commands could be pasted into a terminal, run as a bash script (using ". scriptname") or run as a batch 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.

autocrlf input is a compromise where files are converted to LF-ended on check-in but are not converted back on check-out. This should be considered where WSL (Windows subsystem for Linux" is being used as Linux will usually reject CRLF ended files, but Windows will often tolerate LF-ended files..

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.

MPLAB X Phantom configuration changes

The only remaining oddity is occasional phantom changes caused by MPLAB X re-arranging the XML records in the configuration. This causes a project's configuration file to show up as having changed but with no real difference, which can be cleared by a hard reset to HEAD once it is confirmed that no real edits will be lost.

MCC Phantom include file changes

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

LEGACY CRLF commits

If you have been using MPLAB X GIT un-configured 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.

More specifically if the line ending style is inconsistent this leads to Git rebase reporting that an entire file has changed, despite it looking line-for-line identical. This can be very unnerving when trying to clean up your old commits.

It is advisable 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 as the remote version will be out-of-sync with everyone else's local copies, 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 before anyone else is affected.
  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. I'm not going to claim to be proficient with rebase --onto but it can be the way to go if you need to "graft" 
  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 git's own CRLF conversion and tell you what was actually stored. File identifies file formats by examining their contents. "|" is a pipe that connects the output of one command to the input of another. This command also works for branches and history, just substitute the branch name or commit hash for "HEAD".

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

Incidentally while it is generally reliable there have been occasions where "file" has identified files incorrectly, for example the infamous "Can't print on Tuesdays" bug.