Showing posts with label git. Show all posts
Showing posts with label git. Show all posts

2024-08-19

Adding EDK2 as a submodule without cloning it

Yeah, I have my reasons for this (mostly I commit on Windows, run the builds through GitHub Actions but compile from a non version-controlled Linux, and I don't want to suffer the wastage of yet another lengthy and cumbersome clone of EDK2).

This is mostly taken from https://stackoverflow.com/a/37378302/1069307:

mkdir edk2
git update-index --add --cacheinfo 160000 b158dad150bf02879668f72ce306445250838201 edk2
cat <<EOF >>.gitmodules
[submodule "edk2"]
	path = edk2
	url = https://github.com/tianocore/edk2.git
EOF

Of course, you should replace the commit hash with whatever current or stable EDK2 commit hash you want to point to.

And with this, you'll have added EDK2 as a submodule of your project without going through a cumbersome clone.

2018-10-31

GitHub verified commits with GPG, TortoiseGit and MSYS/MinGW

If you've been browsing git repositories in GitHub, you may have seen that some of them have Verified commits, which is a nice way to indicate that the person who actually committed the code is indeed who they say they are, and not an impersonator who just happened to reuse an e-mail address that is not theirs, for dubious reasons.

Typical display of "Verified" GPG commits in GitHub


Obviously, if you are the only person who has write access to your github repositories (which is how I tend to operate, for obvious security reasons) verified commits are not that much of a big deal. Still, having the badge show in github does help with ensuring that people who are browsing the repo know that you are taking security and trust seriously. So we might as well add commit signing, since it's pretty straightforward to do.

Now, since these are my main development tools, I will hereafter demonstrate how you can do that using TortoiseGit and MSYS/MinGW GPG on Windows. If you use something else, then you will have to look for post entries by other people, that match the tools you use. Also, to give credit where credit is due, I will point out that I am mostly copying Julian's dev.to entry titled "Sign your git commits with tortoise git on windows".

So, without further ado, here's how you should proceed:
  1. Create a new GPG key by firing up a MinGW prompt and issuing the following:

    $ gpg --full-generate-key --allow-freeform-uid
    gpg (GnuPG) 2.2.10-unknown; Copyright (C) 2018 Free Software Foundation, Inc.
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.
    
    gpg: keybox '/home/nil/.gnupg/pubring.kbx' created
    Please select what kind of key you want:
       (1) RSA and RSA (default)
       (2) DSA and Elgamal
       (3) DSA (sign only)
       (4) RSA (sign only)
    Your selection? 1
    RSA keys may be between 1024 and 4096 bits long.
    What keysize do you want? (2048) 4096
    Requested keysize is 4096 bits
    Please specify how long the key should be valid.
             0 = key does not expire
          <n>  = key expires in n days
          <n>w = key expires in n weeks
          <n>m = key expires in n months
          <n>y = key expires in n years
    Key is valid for? (0) 0
    Key does not expire at all
    Is this correct? (y/N) y
    
    GnuPG needs to construct a user ID to identify your key.
    
    Real name: Pete Batard
    Email address: pete@akeo.ie
    Comment:
    You selected this USER-ID:
        "Pete Batard <pete@akeo.ie>"
    
    Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
    We need to generate a lot of random bytes. It is a good idea to perform
    some other action (type on the keyboard, move the mouse, utilize the
    disks) during the prime generation; this gives the random number
    generator a better chance to gain enough entropy.
    We need to generate a lot of random bytes. It is a good idea to perform
    some other action (type on the keyboard, move the mouse, utilize the
    disks) during the prime generation; this gives the random number
    generator a better chance to gain enough entropy.
    gpg: /home/nil/.gnupg/trustdb.gpg: trustdb created
    gpg: key F3E83EBB603AF846 marked as ultimately trusted
    gpg: directory '/home/nil/.gnupg/openpgp-revocs.d' created
    gpg: revocation certificate stored as '/home/nil/.gnupg/openpgp-revocs.d/236D8595DE48618C26293122F3E83EBB603AF846.rev'
    public and secret key created and signed.
    
    pub   rsa4096 2018-10-31 [SC]
          236D8595DE48618C26293122F3E83EBB603AF846
    uid                      Pete Batard <pete@akeo.ie>
    sub   rsa4096 2018-10-31 [E]
    

    You'll notice that, when prompted, we chose to create a 4096 RSA and RSA key that never expires.

    During that process, you will also be prompted to enter the password that safeguards your key. This is the password you will have to enter each time you sign a new commit, so choose it wisely.

    Note that, when using MSYS2 + MinGW, your GPG keys will be stored under C:\msys2\home\<your_user_name>\.gnupg\.
     
  2.  Generate the public key in a format that GitHub can accept:

    $ gpg --armor --export pete@akeo.ie
    -----BEGIN PGP PUBLIC KEY BLOCK-----
    
    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
    =aMFF
    -----END PGP PUBLIC KEY BLOCK-----
    
     
  3. Go to https://github.com/settings/gpg/new and copy/paste the public key data from above.
     
  4. Because we are going to call GPG independently of MinGW, now you must copy your C:\msys2\home\<your_user_name>\.gnupg directory to C:\Users\<your_user_name>\.

    This is needed because this is the default location gpg.exe looks for key when not invoked from msys/MinGW and it doesn't seem possible to alter it without modifying the registry or creating environment variables, which is cumbersome. Besides, this is important data and you are a lot more likely to backup the content of C:\Users\<your_user_name>\ than C:\msys2\home\, so it's probably not a bad idea to duplicate this valuable content there.
     
  5. Get the key id that you'll need to use in your config file with:
    $ gpg --list-keys --keyid-format LONG pete@akeo.ie
    gpg: checking the trustdb
    gpg: marginals needed: 3  completes needed: 1  trust model: pgp
    gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
    pub   rsa4096/F3E83EBB603AF846 2018-10-31 [SC]
          236D8595DE48618C26293122F3E83EBB603AF846
    uid                 [ultimate] Pete Batard <pete@akeo.ie>
    sub   rsa4096/308A9C6106D2FCE4 2018-10-31 [E]

    The 40 characters hex string under pub is the value you are after.
     
  6. In each project where you want to have signed commits, edit your .git/config so that it contains the following options:
    [user]
        signingkey = 236D8595DE48618C26293122F3E83EBB603AF846
    [commit]
        gpgsign = true
    [gpg]
        program = "C:/msys2/usr/bin/gpg.exe"
If you do the above correctly, then next time you commit into the git repo you modified, you should be prompted for your GPG key password, and, after you push to GitHub, you should find that the commit has the Verified badge.

Note that you can also validate whether your commit was properly signed, before pushing, by issuing:
$ git log --show-signature

2011-07-07

git remote repository

If you're like me, you probably have a small Linux server somewhere, begging to be used as a remote central git repository, be it only for the purpose of backing up your development projects on a second machine. A Linux based wireless router or plug computer is perfect for such a job, and, as with any remote VCS, can be invaluable with helping to recover from mishaps on your development rig. And of course, if you're doing development and testing on different computers at once, being able to push/pull from a central server makes your life a lot easier.

Git daemon

By default, git includes a daemon utility to serve clients using the git:// protocol, so you don't even have to install anything extra. The one thing that may matter to you is that the default git daemon does not provide any authentication mechanism, so anybody on your network will be able to push/pull files onto a project. For a SOHO, this isn't a big deal, but in a corporate environment, you may want to look into something a bit more secure.

Our first order of the day then is to decide the directory we want to serve git project from on the server and start the git daemon. In this example, I will use /usr/src on the server. The command to run git daemon then is:
git daemon --reuseaddr --base-path=/usr/src --export-all --verbose --enable=receive-pack --detach --syslog
The --export-all allows pull/clone to be issued by remote clients, regardless of whether a git-daemon-export-ok file exists in the git directory. The --enable=receive-pack is required if you want to be able to push from a client, as it is disabled by default and you will get the error: 'receive-pack': service not enabled for './.git'. The rest of the options should be fairly explicit (if not, see the git daemon page. As you can see, these settings are as permissive as can be, which is probably what you want if you are starting with using git as a server.

Creating the server repository

With the daemon running (check your syslog or messages to confirm), we can now create the directory we want to be used as the origin on our server. Let's call it myproject. Thus:
root@git-server:~# cd /usr/src/
root@git-server:/usr/src# mkdir myproject
root@git-server:/usr/src# cd myproject/
root@git-server:/usr/src/myproject# git init
Initialized empty Git repository in /usr/src/myproject/.git/
Note that the git people historically recommend creating project directory with a .git extension, but there doesn't seem to be much point to it.

Indiana Git and the Intuitiveness of Doom

At this stage, if you have existing files for your project, you have the choice of transferring them to the server and git add + git commit them, or first clone the empty directory on your client and then add the files there. With the latter being the most likely situation, this is what I will demonstrate, therefore (the following was done on Linux - if you are using Msys-git on Windows, see below):
user@git-client:~$ git clone git://git-server/myproject
Cloning into myproject...
warning: You appear to have cloned an empty repository.
user@git-client:~$ cd myproject/
# in real life you would copy, add and commit existing project files there
user@git-client:~/myproject$ touch README
user@git-client:~/myproject$ git add README
user@git-client:~/myproject$ git commit -m "added README"
[master (root-commit) e3cb915] added README
 0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 README
So far so good, but then:
user@git-client:~/myproject$ git push
No refs in common and none specified; doing nothing.
Perhaps you should specify a branch such as 'master'.
Everything up-to-date
OK, googling around shows you need to add origin master to that first push, so:
user@git-client:~/myproject$ git push origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 208 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
remote: error: refusing to update checked out branch: refs/heads/master
remote: error: By default, updating the current branch in a non-bare repository
remote: error: is denied, because it will make the index and work tree inconsistent
remote: error: with what you pushed, and will require 'git reset --hard' to match
remote: error: the work tree to HEAD.
remote: error:
remote: error: You can set 'receive.denyCurrentBranch' configuration variable to
remote: error: 'ignore' or 'warn' in the remote repository to allow pushing into
remote: error: its current branch; however, this is not recommended unless you
remote: error: arranged to update its work tree to match what you pushed in some
remote: error: other way.
remote: error:
remote: error: To squelch this message and still keep the default behaviour, set
remote: error: 'receive.denyCurrentBranch' configuration variable to 'refuse'.
To git://git-server/myproject
 ! [remote rejected] master -> master (branch is currently checked out)
error: failed to push some refs to 'git://git-server/myproject'
Now that's even worse! What the heck?

Long story short, git has a design limitation that prevents it to update both the working directory structure (the user visible files such as 'README', .c/.h, etc.) and the index (the hashed nodes, that contain the same information plus details of the various changes the files went trough) at the same time, on the server. Yes, if they really wanted to, the git developers could easily work around that limitation by providing an option to automatically force a sync on the remote working dir from the index, when index changes have been pushed, but they have decided that, since there exists individual cases where such an option would cause harm, they might as well prevent everybody from doing so altogether, regardless of whether people might be fully aware of what they are doing and accept the consequences.
So this means that, as long as git sees the server git directory being checked out with the 'master' branch, which is the case by default even on an empty directory, as well as the client git repo also using the 'master' branch, which is also the default, it considers that the server repository has precedence (i.e. that there might exist uncommitted changes in the server repo, that have higher priority than any committed client ones), and therefore, will reject remote requests to update the index, such as a push.

To work around that then, you need to make sure that the server doesn't have the 'master' branch checked out locally, when you are issuing a git push from the client. Easiest way to do that is to check into a different branch, away from 'master', on the server, so if we just checkout onto a 'dummy' branch that we create (-b option), git should be happy again. Let's try that:
root@git-server:/usr/src/myproject# git checkout -b dummy
fatal: You are on a branch yet to be born
Right... And people ask me why I'm still not entirely convinced that git is the best invention since sliced bread. Yes, I'll be the first to say that it is usually miles better than the competition, and when it works, it's just brilliant, but quite frankly, there is such thing as intuitive, and as far as intuitive goes, there is still a lot of room for improvement with git.
As the error indicates, the problem this time is that our repo is bare. It doesn't even have a HEAD. Now, because we don't have all day to figure out each of git's numerous intricacies, we just take matters into our own hands and hook into the git index directly with:
root@git-server:/usr/src/myproject# git symbolic-ref HEAD refs/heads/dummy
This should ensure that git no longer sees us as potentially modifying the (still non-existing) 'master' branch on the server and stop bugging us.

Then, if you go back to the client:
user@git-client:~/myproject~ git push origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 208 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To git://git-server/myproject
 * [new branch]      master -> master
At last, success!! From there on you should be able to use a naked git push on the client and roll.
If you later want to edit/modify the repo content on the server (the server working dir will remain empty even after a push, because the working directory is no longer following the 'master' HEAD), you can do so by switching back to the 'master' branch with git checkout master. Then an up to date version of what you have pushed should be in your server working dir. However, remember that, if you are planning to remotely push some more, you need to use either git checkout [-b] dummy (if you don't mind having a dummy branch created) or git symbolic-ref HEAD refs/heads/dummy (if you don't want a branch) on the server when you are done, to prevent git from rejecting the operation. If you use the latter, be mindful that you will get a warning: remote HEAD refers to nonexistent ref, unable to checkout error (yes git, if it results in a failure, it is an error, not a warning), so you may have to go back to your server and set symbolic-ref to 'master' before cloning. And if you use the former, make sure that's you're working on the 'master' branch and not 'dummy' after cloning.

Yay, now we have a working git server, and more importantly, we know how to work around the various counter-intuitive git limitations to create repositories on it... Of course, that is, as long as you don't use msys-git on Windows 7...

What's wrong with git daemon and msys-git?

OK, so we are sorted out on Linux. How about we try the same thing on Windows 7 with msys-git?
user@WINDOWS ~
$ git clone git://git-server/myproject
Cloning into myproject...
remote: Counting objects: 8, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 8 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (8/8), done.

user@WINDOWS ~
$ cd myproject/

user@WINDOWS ~/myproject (master)
$ echo "test" > README

user@WINDOWS ~/myproject (master)
$ git add README
warning: LF will be replaced by CRLF in README.
The file will have its original line endings in your working directory.

user@WINDOWS ~/myproject (master)
$ git commit -m "edited README"
[master warning: LF will be replaced by CRLF in README.
The file will have its original line endings in your working directory.
a0f27c3] edited README
warning: LF will be replaced by CRLF in README.
The file will have its original line endings in your working directory.
 1 files changed, 1 insertions(+), 1 deletions(-)
So far, so good. But then, if you issue git push the command hangs forever:
user@WINDOWS ~/myproject (master)
$ git push
Counting objects: 5, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3)
On the server, the log doesn't seem to indicate that much is amiss:
Jul  7 16:22:23 git-server git-daemon[7324]: Connection from 1.2.3.4:51238
Jul  7 16:22:23 git-server git-daemon[7324]: Extended attributes (13 bytes) exist <host=git-server>
Jul  7 16:22:23 git-server git-daemon[7324]: Request receive-pack for '/myproject'
Congratulations! You've just encountered msys-git bug #457 for which no patch exists yet. If you want a workaround, you can either switch to using ssh (but then you need to sort out authentication, which, for a single-user internal-only VCS operation is a bit of an overkill) or share your repository with samba, and then add the following in the [remote "origin"] section from .git/config:
pushurl = file:////git-server/src/myproject
As can be inferred the above simply forces git to use Samba rather than the git protocol for push operations. With this workaround in place, you are truly set to use a remote git server.

ADDON: The following script might be used as a very useful first commit for the server repository, as it helps toggle between the ability to commit files on the server and allowing client commits:
#!/bin/sh
git branch | grep -q \*
if [ $? -eq 0 ]; then
  git symbolic-ref HEAD refs/heads/dummy
  echo "Switched to fake branch 'dummy'"
else
  git symbolic-ref HEAD refs/heads/master
  echo "Switched to branch 'master'"
fi

2011-02-11

Denying non-fast-forward and SourceForge

Well, I have it from good source that deleting commits, on a public source, is actually fine if you have a good reason to do so. But what if that public source happens to be a git repositoty on SourceForge?

Let's say you wanted to push some code modifications, so you added a source (or so you thought), but realize after commit & push, that what you really added was the binary rather than the .c. Don't want your public repo to be polluted by unneeded binaries.

So you tried:
git reset --hard HEAD~1
git push origin +master:master
or
git commit --amend
but every time you push you get the error:
error: denying non-fast-forward refs/heads/master (you should pull first)
To ssh://USER@PROJECT.git.sourceforge.net/gitroot/PROJECT
 ! [remote rejected] master -> master (non-fast-forward)
error: failed to push some refs to 'ssh://USER@PROJECT.git.sourceforge.net/gitroot/PROJECT'
What gives?

A good search will of course lead you to ticket #9187 and receive.denyNonFastforwards being set to true by default on the remote git repository provided by SourceForge.

How can you edit your remote config to unset denyNonFastforwards? Easy:
ssh -t USER,PROJECT@shell.sourceforge.net create
[USER@shell-24010 ~]$ sf-help
(...) 
Your project DSCM repositories are here (use adminrepo for CVS and SVN):

    /home/scm_git/U/US/USER.u
    /home/scm_git/P/PR/PROJECT
(...)
[USER@shell-24010 ~]$ cd /home/scm_git/P/PR/PROJECT
[USER@shell-24010 PROJECT]$ ls -alFh
total 12K
drwxrwsr-x 3 dummy PROJECT   80 Nov 29 19:15 ./
drwxr-xr-x 3 root  root    4.0K Feb 10 21:58 ../
drwxrwsr-x 7 dummy PROJECT 1.0K Nov 29 19:15 PROJECT/
[USER@shell-24010 PROJECT]$ cd PROJECT
[USER@shell-24010 PROJECT]$ ls -alFh
total 48K
drwxrwsr-x   7 dummy PROJECT 1.0K Nov 29 19:15 ./
drwxrwsr-x   3 dummy PROJECT   80 Nov 29 19:15 ../
-rw-rw-r--   1 dummy PROJECT   23 Nov 29 19:15 HEAD
drwxrwsr-x   2 dummy PROJECT   80 Nov 29 19:15 branches/
-rw-rw-r--   1 dummy PROJECT  126 Nov 29 19:15 config
-rw-rw-r--   1 dummy PROJECT    5 Nov 29 19:15 description
drwxrwsr-x   2 dummy PROJECT 1.0K Nov 29 19:15 hooks/
drwxrwsr-x   2 dummy PROJECT   80 Nov 29 19:15 info/
drwxrwsr-x 133 dummy PROJECT 5.0K Feb 10 21:41 objects/
drwxrwsr-x   4 dummy PROJECT   80 Nov 29 19:15 refs/
Yay, there's a config there:
[USER@shell-24010 PROJECT]$ vi config
Then remove/unset that pesky denyNonFastforwards and you're good to go.