Skip to content

Hacking with Git on FreeBSD repos

Daniel Engberg edited this page Jan 30, 2024 · 12 revisions

Here's an alternative to using branches if you're concerned about by mistake pushing bad commits and/or changes to the ports repo using two separate repos, one dev and one commit.

Legend

  • Tracked file(s)
    Files that git is already aware of (existing files in a repo)
  • Cached file(s) (git documentation also refers this state as stashed)
    Files that are to be added or in some cases files that are to be updated (if git add is used)

Create a dev repo

This is where you do all work/development/testing and generating patches with commits for upstreaming.
For the sake of simplicity let's use /usr/ports

git clone https://git.FreeBSD.org/ports.git /usr/ports
While it mainly affects initial pull (download) https://codeberg.org/FreeBSD/freebsd-ports.git is a lot faster for me

Basic commands

Initially there will be 4 commands you need to care about (high-level commands (porcelain) as git documentation refers them as) for the dev repo and a few variants:
git diff
git diff --cached
git add .
git add <MyNewFile>
git reset --hard HEAD
git pull --ff-only

  • git diff
    Generates a "friendly" patch which also works with FreeBSD's patch utiity in base.
    It will not work if you've executed git add to add new files.
  • git diff --cached
    Will only work (as you'd expect it work) if you've executed git add to add files / directories
    It can also generate git specific patches that moves files around however patch in base will ignore such operations
  • git add .
    Will add and update all files including subdir(s) in current path
    Strongly recommend is that you do not make a habit of using it in root dir simply because you're likely to add files unintentionally especially if you're working on multiple ports, only use it in a specific port directory. It'll also ignore any changes you've done to existing files outside the path so you need to add those as well, see Example 2. If you added a file by mistake you can also remove it from that cache by removing the file and executing git add ..
  • git add <MyNewFile>
    Despite its name it actually does two things, add a specific file to your cache or update an existing one if you've executed git add earlier.
  • git reset --hard HEAD
    Will reset any changes made to tracked files and ones in your cache, it will not however remove or reset files that you have in a directory but not added by git add.
  • git pull --ff-only
    Pulls in all new changes from the tree, it will also fail upon any kind of conflict This is handly because you don't want your tree to diverge

Caution

While git in general is pretty smart it will not track updates in files you've added using git add. In that case you need to execute git add . or git add <MyNewFile> again to update the cache.

Create a commit repo

Follow this section https://docs.freebsd.org/en/articles/committers-guide/#git-mini-daily-use

In addition to the above you'll likely find it easier to set an editor such as nano.
git config core.editor "nano"

A few new commands

git apply <MyPatchFile>
git commit -a -m "A/B: Foo"
git commit -a -m "A/B: Foo" --author "John Doe <jd@dishracksrules.org>"
git commit --amend
git reset --hard <HASH>
git am <MyPatchFile>
git pull --rebase
git log git push -v freebsd
git push --push-option=confirm-author -v freebsd

  • git apply <MyPatchFile> Applies patch file without any meta data
    Note: Git is very noise about white space in patch issues but these can in general safely be ignored
  • git commit -a -m "A/B: Foo" Initialize the process if committing non cached or cached changes. Git will assume that you're the sole author of the change(s), if not you should use the command below. A/B: represents the path and Foo the title (summary) of your commit message Tip: Pay attention to the bottom as it will list files changed by this commit
  • git commit -a -m "A/B: Foo" --author "John Doe <jd@dishracksrules.org>"
    Same as above but the --author part refers to author of the patch other than the committer
  • git commit --amend
    Allows you to edit the commit message of the most recent commit in your tree. You can not edit author meta data, in that case you need to revert the commit and start over using git reset`.
  • git reset --hard <HASH>
    Reset all changes and revert to referred hash (use full hash)
  • git am <MyPatchFile>
    Applies patch file with a single commit or multiple with meta data.
    Tip: Be a bit careful using this one as meta data wont always be correct.
  • git pull --rebase
    Pulls in all new changes and tries to apply your local commits on top of the new commits (from upstream repo).
    To keep it simple only use this when trying to push local commits and when git errors out because your tree is not up to date. If you don't have any local changes always use git pull --ff-only instead. As a rule of thumb always execute git pull --ff-only before applying patches to the tree.
  • git log List commits sorted by newest first
  • git push -v freebsd Push your local changes upstream, always use this by default unless you have committed patches with other authors than yourself. You'll get an erorr about it if you're trying to push commits with other authors.
  • git push --push-option=confirm-author -v freebsd
    Same as above but allows commits with other authors than yourself

Examples

Example 1

Update port with existing files and/or remove existing ones

cd /usr/ports/multimedia/musicpuff
...
rm -rf files
git diff > /home/jigglypuff/musicpuff-port.patch

Example 2

New port (with Makefile etc already created)

cd /usr/ports/multimedia/musicpuff
git add .
cd ..
git add Makefile
git diff --cached > /home/jigglypuff/musicpuff-port.patch