git-preserve-permissions
git-preserve-permissions copied to clipboard
Save user name and group name rather than UID, GID
Hi - I'm working in between systems -- Mac, Linux, BSD. I have the same users and groups on all the systems however the UIDs and GIDs don't match. When I run this program on MAC to save permissions I get something like:
0775:501:20:post-merge
I believe 501 refers to UID and 20 is GID, however these aren't going to match up on the remote systems.
If they were save like
0775:kevdog:wheel:post-merge
then this would actually work.
Indeed. Unfortunately, the chown perl function needs numeric IDs and can's use names. Thus, if we want to support this, we'll have to transform names into ids before ownership restauration.
Do you really need to save the user and group information?
Hey thanks for responding. Ive never programmed in perl but after looking at your code, I can't say I understand everything it does, but I definitely was able to find the chown block and lstat statements and understood where you were getting and setting the uid and gids. I was able to make a few modifications to the code for it to actually store the user and group names. I think this is a little more practical then storing uids and gids since these numbers are likely to be different on the machines they pull the code. It's one thing to have the same user and group names on different machines but it's a heck of a lot more burdensome to actually have the same uid and gids particularly if these numbers are already taken. I'm in the process of testing things right now to see if the code actually works as intended with the modifications. I'm working back and forth between osx, bsd and Linux to test things. Unfortunately I don't think the code is meant for windows and that's OK for my requirements
On Thu, Oct 17, 2019 at 2:32 PM Christophe Drevet-Droguet < [email protected]> wrote:
Indeed. Unfortunately, the chown perl function needs numeric IDs and can's use names. Thus, if we want to support this, we'll have to transform names into ids before ownership restauration.
Do you really need to save the user and group information?
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/dr4Ke/git-preserve-permissions/issues/4?email_source=notifications&email_token=ABH75V7ZAZAAWAC76WOPDD3QPC4URA5CNFSM4JB3L4EKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEBRIJRA#issuecomment-543327428, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABH75V3UBP6MJ2IIVHG63FTQPC4URANCNFSM4JB3L4EA .
Ok - reviewing your code I have a question since the restore part isn't working. My setup for testing is I have a push repository (server pushing changes to git) and a pull repository (server pulling changes from git). I'd like the permissions,owner,group data to be propogated from push repository to pull repository.
So the main options I don't understand (See below) -- Do I need to set these options on either the save or restore side??
preserve-permissions.user: true/false to save/restore uid (defaults to false) preserve-permissions.group: true/false to save/restore gid (defaults to false) preserve-permissions.perms: octal mask to select bits to save/restore (defaults to 0700)
I would take this as preserve-permissions.user = true -> save permissions of user, preserve-permissions.user = true -> save permissions of user so for example ${options{'user'}}=1 -- save user permissions ${options{'user'}}=0 -- restore user permissions (which is default setting)
However based on this assumption, the restore isn't actually happening -- but the save is.
Going with the defaults (not setting any of these variables) -- on the main/push side the file permissions (octal) and username/groupnames are saved -- after I made changes to the code to write username/groupname rather than UID/GID. Here is snippet:
#FORMAT:1.3
0644:kevdog:staff:.git-preserve-permissions
0644:kevdog:kevdog:README.md
0644:kevdog:kevdog:ansible.cfg
0755:kevdog:kevdog:git-preserve-permissions
0755:kevdog:kevdog:post-checkout
0755:kevdog:kevdog:post-merge
0755:kevdog:kevdog:pre-commit
0644:kevdog:kevdog:vars.ym
However during the restore function (gpg_restore) there is a call to
if (check_ids($file, $uid, $gid) != 0)
Within check_ids:
if ($options{'user'} and ($actual_uid != $uid)) {
file_status_print($file,
'user changed from '.$uid.' to '.$actual_uid);
$result = 1
}
$options{'user'} always defaults to zero and hence this function will never return 1 and hence restore command will not get executed.
So in summary to restore everything similar to permission on push server $options{'user'} = 1; $options{'group'} = 1; $options{'perms'} = 0777;
For saving the defaults can be used.
Ok - Code tested and seems be working Assumptions -- user and group names must exist on all location using script On locations where you want the original file permissions, user names, and group names to be restored, I used the following settings:
git config preserve-permissions.user true
git config preserve-permissions.group true
git config preserve-permissions.perms 0777
Here are changes:
145c145,148
< ($actual_mode, $actual_uid, $actual_gid) = (lstat($file))[2,4,5];
---
> # ($actual_mode, $actual_uid, $actual_gid) = (lstat($file))[2,4,5];
> $actual_mode = ((lstat($file))[2]);
> $actual_uid = getpwuid((lstat($file))[4]);
> $actual_gid = getgrgid((lstat($file))[5]);
146a150
>
156c160
< $actual_gid if $debug;
---
> $actual_gid if $debug;
173c177,178
< if ($options{'user'} and ($actual_uid != $uid)) {
---
>
> if ($options{'user'} and ($actual_uid ne $uid)) {
178c183
< if ($options{'group'} and ($actual_gid != $gid)) {
---
> if ($options{'group'} and ($actual_gid ne $gid)) {
287c292,295
< my ($mode, $uid, $gid) = (lstat($parent))[2,4,5];
---
> # my ($mode, $uid, $gid) = (lstat($parent))[2,4,5];
> my $mode = (lstat($parent))[2];
> my $uid = getpwuid((lstat($parent))[4]);
> my $gid = getgrgid((lstat($parent))[5]);
295c303,306
< my ($mode, $uid, $gid) = (lstat($file))[2,4,5];
---
> # my ($mode, $uid, $gid) = (lstat($file))[2,4,5];
> my $mode = (lstat($file))[2];
> my $uid = getpwuid((lstat($file))[4]);
> my $gid = getgrgid((lstat($file))[5]);
333,336c344,349
< $uid = -1 if (not $options{'user'});
< $gid = -1 if (not $options{'group'});
< printf "%s: Restoring owner:group to %s:%s\n", $file, $uid, $gid if $verbose;
< chown $uid, $gid, $file;
---
> my $uiid = getpwnam($uid);
> my $giid = getgrnam($gid);
> $uiid = -1 if (not $options{'user'});
> $giid = -1 if (not $options{'group'});
> printf {STDERR} "%s: Restoring to owner[uid]:group[gid] to %s[%s]:%s[%s]\n", $file, $uid, $uiid, $gid, $giid if $verbose;
> chown $uiid, $giid, $file;