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

Monday, October 15, 2018

'commit' changes on webserver to Github repo using PHP not working

Leave a Comment

I'm trying to write a little PHP script that can spot all the changes to a local git repo on my web server and push them up to my (private) Github repo. Pushing and pulling from the Github repo using Atom works perfectly, pushing changes to the web server using a webhook works perfectly, pushing and pulling updates on the web server via the command line works perfectly, my problem is trying to commit and push updates on the web server to my Github repo using PHP. How do you do this?

If I have to change, add or even delete an entire template on the server manually I can commit those changes and push them up to Github using the command line like this no problem:

git add --all git commit -m "from server" git push -u origin master 

But when I try to do this using a PHP script it never works and I get no error message (I even try with pauses):

$output = `git add --all`; echo $output; sleep(1);  $output = `git commit -m "from server"`; echo $output; sleep(3);  $output = `git push -u origin master`; echo $output; sleep(3); 

If I run something simple like 'git --version', 'git config --list' or 'git status' it works perfectly from these scripts, so I'm at a loss.

4 Answers

Answers 1

When you run a script with php it is run by a user www-data(by default). When you connect to git repository you need to do auth. Most likely it will be done using ssh key. So you need authorize user www-data with the ssh key to allow him accessing the remote repository.

So the steps.

  1. Generate key
  2. Add the key to the remote repository
  3. Add the key to ssh agent locally for user www-data
  4. Check the enviroment where you run the command
  5. Enjoy

Useful link: https://help.github.com/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent/

There's also an option to use authentication via https with skipping putting credentials. You can see more here

Moreover, there's the library that does such things you may check it as well

Answers 2

You says:

But when I try to do this using a PHP script it never works and I get no error message (I even try with pauses):

$output = `git add --all`; echo $output; sleep(1);  $output = `git commit -m "from server"`; echo $output; sleep(3);  $output = `git push -u origin master`; echo $output; sleep(3); 

If I run something simple like 'git --version', 'git config --list' or 'git status' it works perfectly from these scripts, so I'm at a loss.

It seems like you have no write permission here.

You can easily run following commands to check permission for git repo, login user and owner of web server.

Run command whoami or id to identify login user.

$ whoami gasolwu $ id uid=501(gasolwu) gid=20(staff) groups=20(staff),501(access_bpf),12(everyone),61(localaccounts),79(_appserverusr),80(admin),81(_appserveradm),98(_lpadmin),33(_appstore),100(_lpoperator),204(_developer),250(_analyticsusers),395(com.apple.access_ftp),398(com.apple.access_screensharing),399(com.apple.access_ssh),701(com.apple.sharepoint.group.1) 

List directory to check owner and permissions for given path (git repo)

$ ls -al /path/to/repo total 16 drwxr-xr-x   5 gasolwu  staff  160 Oct 15 21:50 ./ drwxr-xr-x   5 gasolwu  staff  160 Oct 15 21:48 ../ drwxr-xr-x  13 gasolwu  staff  416 Oct 15 21:53 .git/ -rw-r--r--   1 gasolwu  staff  196 Oct 15 21:50 git.php* -rw-r--r--   1 gasolwu  staff   79 Oct 15 21:49 git.sh* 

Show process status to check user whom runs web server

$ ps auxwww | grep 'httpd\|nginx\|apache' _www              1139   0.0  0.0  4342760   3692   ??  S     9:51PM   0:00.01 /usr/sbin/httpd -D FOREGROUND _www              1138   0.0  0.0  4351976   3692   ??  S     9:51PM   0:00.02 /usr/sbin/httpd -D FOREGROUND _www              1137   0.0  0.0  4317160   1988   ??  S     9:51PM   0:00.01 /usr/sbin/httpd -D FOREGROUND _www              1129   0.0  0.0  4334568   2300   ??  S     9:51PM   0:00.01 /usr/sbin/httpd -D FOREGROUND root              1119   0.0  0.1  4316156  11772   ??  Ss    9:51PM   0:00.51 /usr/sbin/httpd -D FOREGROUND gasolwu           1465   0.0  0.0  4268036    824 s000  S+   10:19PM   0:00.00 grep --color=auto -d skip httpd\|nginx\|apache 

or check user of php-fpm if you run web sever with PHP-FPM

$ ps auxwww | grep php-fpm gasolwu           1761   0.0  0.0  4268036    812 s000  S+   10:33PM   0:00.00 grep --color=auto -d skip php-fpm nobody            1737   0.0  0.0  4323216    724   ??  S    10:33PM   0:00.00 php-fpm nobody            1736   0.0  0.0  4323216    732   ??  S    10:33PM   0:00.00 php-fpm root              1735   0.0  0.0  4323216    920   ??  Ss   10:33PM   0:00.00 php-fpm 

As you can see, It also has permission problem here, The .git directory can only be written by user gasolwu, not web user _www. So when you run git operation via php script through web server. .It can't do git operation (add/commit) without write permission.

The shell_exec (is identical to the backtick operator) function only returns stdout, It's empty here when error occurs, The stderr will be redirected to error log base on your environment, You will get similar error message log in Apache or PHP.

$ cat /var/log/apache2/error_log Mon Oct 15 21:51:06.734474 2018] [mpm_prefork:notice] [pid 1119] AH00163: Apache/2.4.34 (Unix) PHP/7.1.19 configured -- resuming normal operations [Mon Oct 15 21:51:06.734572 2018] [core:notice] [pid 1119] AH00094: Command line: '/usr/sbin/httpd -D FOREGROUND' fatal: Unable to create '/path/to/repo/.git/index.lock': Permission denied fatal: Unable to create '/path/to/repo/.git/index.lock': Permission denied error: could not lock config file .git/config: Permission denied error: Unable to write upstream branch configuration hint: hint: After fixing the error cause you may try to fix up hint: the remote tracking information by invoking hint: "git branch --set-upstream-to=origin/master". error: update_ref failed for ref 'refs/remotes/origin/master': cannot lock ref 'refs/remotes/origin/master': Unable to create '/path/to/repo/.git/refs/remotes/origin/master.lock': Permission denied Everything up-to-date error: remote unpack failed: unable to create temporary object directory To /tmp/git  ! [remote rejected] master -> master (unpacker error) error: failed to push some refs to '/tmp/git' 

Let's fix it by given write permission to right user (_www here).

chown -R _www /path/to/repo 

After that, you can send request to http://example.com/git.php to add files, commit with message "from server" then push them to GitHub.

CAVEAT: There is some security concern for this methodology without authentication.

Answers 3

The problem is with the authentication. The first solution is to do like Robert said. But I think that no need to Reinvent the wheel, try to see this package :

https://github.com/kbjr/Git.php

Everything is already there.

Answers 4

You are literally just echoing strings, not running them.

Instead of echo(), you can use exec(), shell_exec():

http://php.net/manual/en/function.exec.php

http://php.net/manual/en/function.shell-exec.php

Here are the PHP commands that allow you to execute programs on the server:

http://php.net/manual/en/ref.exec.php

Read More

TeamCity prevent simultaneous branch builds

Leave a Comment

I have a Git setup with the typical master --> develop --> feature structure. I have 5 TeamCity (v8.1) build agents. Is it possible to configure TeamCity so that if multiple people commit to develop at the same time, the develop branch won't run concurrent builds? Part of our CI process is deploy-on-success, so I don't want two builds to be deploying to the same endpoint at the same time.

(I would want this setup for all branches, not just develop)

3 Answers

Answers 1

On the General Settings configuration page you can set the number of simultaneous builds to 1 instead of 0 for unlimited. This means that it am queue up say 5 builds but only 1 will run at a time.

Answers 2

Are you trying to prevent multiple check-ins to the same branch from generating multiple builds for that branch? You can do this without changing the concurrency settings by settings some options on the VCS Trigger portion of your build configuration. There is a 'Quiet Period' setting that waits for X seconds before doing a build, just in case several commits come in at once.

Here's a screenshot of the relevant menu in TeamCity 8.x:

Screenshot of the TeamCity menu for configuration the quiet period on a build configuration.

EDIT: Another option is the Build Features -> Shared Resource feature. This allows you to create a lock, associate it with one or more projects, and have them use it. This is useful to prevent 1+ projects from building at the same time. This is more reliable than the quiet time feature since there is an actual lock and not just a delay, though the quiet time does help collect multiple near-simultaneous checkins and so is independently useful.

Answers 3

Combining a quiet period long enough, but not too long :), and 1 build max at same time, you should be able to get what you want. It's what we use here, quiet period from 120 to 180 seconds, and it works well.

Read More

Thursday, October 4, 2018

How to clone/fetch a repo getting only the history

Leave a Comment

Is it possible to download a repository's commits, branches, and tags, excluding blobs and trees? I would like to be able to view the history and whatnot without downloading the files (this is for the Chromium repo, which is multiple gigs). Obviously I will not be able to see which files were affected by a commit, but that's fine.

3 Answers

Answers 1

No, or at least, not using any ordinary access. Some sites offer web access, through which you can obtain the contents of every commit object without also obtaining tree and blob objects, but the normal process of receiving objects or thin packs is either truncated at the commit level (via --depth) or is complete.

You can of course see all visible tags with git ls-remote as well as through any sensible web interface (it would be weird to provide something like GitHub's fancy API if you didn't provide the tags that way :-) ).

Note that traversing all commits via a web API may be tremendously slow, either due to having to stop and wait (if you program it synchronously rather than as a streaming process) or due to rate limiting software on the host (GitHub and Bitbucket both seem to do rate limiting).

Answers 2

We are building ghuser.io (enhanced GitHub profile pages) and any way to get the commit history without files would help us tremendously to scale.

Then you would need to setup a mirror server with GVFS (Git Virtual File System) / VFS For Git support.

Since June 2016 (the OP question) and now (Q4 2018), VFS For Git (since issue 72 is soon to be resolved) has been proposed by Microsoft (Feb. 2017), and allows you to develop with TeraBytes repos(!) without having the files downloaded.

GitHub itself should support it soon.

See more at gvfs.io, although I suspect that domain name should be renamed soon to reflect the new "VFS For Git" name: possibly to: https://www.vfsforgit.org.

Answers 3

You can achieve this with github apis.

https://developer.github.com/v3/repos/commits/#list-commits-on-a-repository

Read More

Tuesday, September 25, 2018

Proper way to proceed when upstream gets ahead from incomplete PR?

Leave a Comment

INTRODUCTION

I've forked a repository that follows the so-called "git flow" and has to develop/master/factory branches. I'll reference from now on my fork as origin and the main repository as upstream.

After opening an issue and talk/agree on few things with the repo maintainer I started working on it. The first thing I did was creating a feature branch tracking (origin/develop).

After few temporary commits with temporary throw-away temporary bad names, I'd created a PR and pushed. The idea I had in mind was eventually squashing all my commits on a single one and then providing a proper commit name/description so the maintainer would be able to merge all of it to upstream/develop without any problems, my main goal was making the whole process as smooth as possible both for me and the upstream maintainer, once merged I'd happily delete my local branch, job done, easy peasy... :)

PROBLEM

I was naive thinking that would go so smoothly!

I'm not a git expert by any means and I was wrong thinking the PR would evolve so smoothly (this tend to happen when you don't know really the tools you're using). At a certain point, I'd stopped working on my PR for few days and obviously upstream/develop continued evolving and getting far away ahead of my PR, my PR wasn't passing the tests yet and the whole PR was still pending unfinished job.

A few days later I decided to come back to that PR and tried to resume my work, after fetching upstream/develop I'd seen many upstream commits were already far away ahead from my PR and I didn't really know what was the best choice on that particular situation, I didn't know and I still don't know whether merging or rebasing is the best choice...

With little knowledge about the possible implications about merging or rebasing I decided merge couldn't be that bad and everything would be possible to tidy up eventually, right? Well, as a result, after merging and pushing some more temporary commits my local history has become a little bit messy and I don't really know whether this can be cleaned somehow without messing up the upstream history.

Let's say the history looks something like PR=c1->c2->c3->upstream1->upstream2->upstream3->c4->c5. In that example c1..c6 would be my local changes and upstream1..upstream3 would be committing ahead from upstream.

QUESTIONS

  • Was my decision of merging a really bad choice when upstream got very far away ahead from my unfinished PR? What would have been the best way to proceed in that case? Consider my goal is ending up with a single squashed commit merged into upstream eventually
  • Once the harm is done and I've merged after solving the conflicts and created few more commits, would still be possible to provide a clean PR with just 1 single squashed commit without rewriting upstream history?

I guess the whole thread could be summed up by asking what's the best way to proceed when upstream gets far away from your unfinished PR that contains multiple temporary commits.

3 Answers

Answers 1

I'll tell what I do in such a case. This approach is highly practical and probably different people have different personal choices.

I also, like you, strive to squash commits to 1 commit in PR.

So let's say, there is a dev branch.

When I start a feature branch I do:

>> git checkout dev >> git pull >> git checkout -b feature_branch >> commitA >> commitB >> git push -u origin feature_branch // now there is origin/feature_branch available to everyone >> and create a PR when I'm ready 

Now the process goes like this:

People review my work and comment, I make my changes and commit. It's a kind of loop, it ends where all of us are satisfied with these changes and ready to merge things back

>> commitC >> commitD 

So, now I'm ready to "squash my commits into one". So I do:

>> // make sure I'm on feature_branch >> git rebase -i HEAD~4 >> // at this point I have one 'beautiful' commit, lets_call it commit_TO_GO >> git push -f //forcefully push my commits by overriding the current state of a remote branch in PR, this is not really important, only if I want to "preserve this state for backup or something 

As long as this branch is not merged, I don't mind to do this, it doesn't matter.

Let's pretend that this process has taken some time, and meanwhile, there are some new commits in the origin/dev branch (commitX, commitY and commitZ) done by other teammates.

So, in theory, I can now do the following: Merge by applying a regular 3-way merge, if there are conflicts I'll have to resolve them first of course.

However, since I'm concerned about the history of commits (like you're), I do the following:

>> git fetch --all  >> git rebase origin/dev >> // at this point The my commit_TO_GO is applied on top of commitX,commitY,commitZ.  >> // technically it has a different sha1 now, but it's not really important, its  >> still my own branch, I do whatever I want there :) >> git push -f // again forcefully push to origin/feature_branch 

After this step, the origin/feature_branch is FF from origin/dev, which is cool, because I can apply merge and it will be in an FF mode, even merge commit won't be created.

Of course, if there are conflicts the rebase won't work, I'll have to resolve the conflicts first. I do this in my IDE and then continue the rebase (git rebase --continue), but conflict resolution is beyond the scope of this question

Now I'm ready to merge my change back to origin/dev

Usually, I do it in UI of bitbucket/github.

After the merge the history in origin/dev looks beautiful:

commitX->commitY->commitZ->commit_TO_GO 

Result: No merge commits at all, my single commit is applied last

One Point to consider:

Its worths nothing to rebase from dev branch even during your development (while you're working on feature_branch), just to make sure it contains the latest changes. So you can go through the loop as many times as you want:

 >> git fetch --all   >> git rebase origin/dev 

I understand that probably Git has more "shortcut commands" up its sleeves, and maybe this explanation was too detailed.

Answers 2

In terms of end results, merging and rebasing is the same... However, in terms of the resulting history and how easy it would be to be able to move around your work 'in isolation', they are way different... If you work, then merge, then work more... Then merge... Then work some more and so on, it's very difficult to see all the revisions that make up the work of this feature alone.

All of this to say: just rebase. What should do? Go to the tip of upstream/develop, cherry-pick the real revisions that make up the feature work (no merges)... This way, you cleaned up the branch... Set the local feature pointer to this point and continue working... If more work is done on upstream/develop, then rebase on top of it.

Answers 3

As others mentioned above, I will choose to use git rebase as below.

topic is your pull request and in the meanwhile master branch is involved with another commits.

      A---B---C topic      / D---E---F---G master 

rebase means to change the previous base which also modify the history of your branch.

              A'--B'--C' topic              / D---E---F---G master 

As a result, you have to force push to your remote branch. Because no one has merged your PR before, it is OK and makes no impact to your collaborators.

You can read more details about rebase here: Pro Git v2, Git Branching - Rebasing and git-rebase command.

Read More

Monday, September 3, 2018

Use local repo in satis repository

Leave a Comment

I have a server in which I have a few git repos and a satis repository setup. I'd like to setup the satis repository to list the local repos.

// satis.json {   "name": "NJ16 Repositories",   "homepage": "http://packages.example.com",   "repositories": [         {              "type": "vcs",              "url": "https://bitbucket.org/nicholasjohn16/example.git"          },         {             "type": "vcs",             "url": "git@example.com:/var/repo/test-repo.git"         }   ],   "require-all": true,   "output-dir": "web/" } 

When I run this, the bitbucket git repo is accessed and updated successfully, but when satis gets to building the local git repo it hangs at the following lines and doesn't continue.

Executing command (/root/.cache/composer/vcs/git-example.com--repo-test-repo.git): git rev-parse --git-dir Executing command (/root/.cache/composer/vcs/git-example.com--repo-test-repo.git): git remote -v Executing command (/root/.cache/composer/vcs/git-example.com--repo-test-repo.git): git remote set-url origin 'git@example.com:/repo/test-repo.git' && git remote update --prune origin 

I've tried using ../../repo/test-repo.git and /var/repo/test-repo.git for the repo url. When I do this, the build completes successfully, but when I try to require it with composer, I get the following error.

[RuntimeException]                                                                                                                       Failed to execute git clone --no-checkout  "C:\wamp\www\nj16\nicholasjohn16\vendor\NicholasJohn16\test-repo" && cd /D "C:\wamp\www\nj16\nicholasjohn16\vendor\NicholasJohn16\test-repo" && git remote add composer  && git fetch composer  Cloning into 'test-repo'...                          fatal: 'C:\wamp\www\nj16\nicholasjohn16\vendor\NicholasJohn16\test-repo' does not appear to be a git repository fatal: Could not read from remote repository.                                                                                             Please make sure you have the correct access rights and the repository exists.   

Though, it does make reference to the most recent commit hash so I know it's atleast fetching the repo successfully, but satis doesn't seem to have access to the data.

How can I do this correct? Any assistance is appreciated.

JFYI, git is a user and has their own ssh key which is added to authorized_users so they can clone their own repo.

1 Answers

Answers 1

Hi please make sure your are running proper command and path

then fallow below path

please go to you repo path (C:\wamp\www\nj16\nicholasjohn16\vendor\NicholasJohn16\test-repo)

And initialize the empty repository

git init

then set a remote also iy you want then git remote add composer github-url

Then add a branch if requires

git branch slave

Then checkout to slave branch

Then use

Note 1: please run one after one then you will get know what is the failure is

Note 2 : please re check your command which your running

Note 3 : fallow my steps

Read More

Sunday, June 3, 2018

git clone works but push doesn't after replacing SSL certificate behind firewall

Leave a Comment

Cloning my repo works; pushing back to it doesn't.

1st cloning did not work:

git clone https://github.com/slimsnerdy/testy.git Cloning into 'testy'... fatal: unable to access 'https://github.com/slimsnerdy/testy.git/': SSL certificate problem: self signed certificate in certificate chain 

So I added to the .gitconfig file the following custom certificate:

[http]     sslCAInfo = U:/ca-bundle.crt 

Now cloning works:

Cloning into 'testy'... remote: Counting objects: 25, done. remote: Compressing objects: 100% (22/22), done. remote: Total 25 (delta 8), reused 6 (delta 1), pack-reused 0 Unpacking objects: 100% (25/25), done. 

Ok now pushing:

new-item test.txt git add * git commit -m "push test" git push Username for 'https://github.com': slimsnerdy Password for 'https://slimsnerdy@github.com': remote: Anonymous access to slimsnerdy/testy.git denied. fatal: Authentication failed for 'https://github.com/slimsnerdy/testy.git/' 

When I try to push via a personal hotpot using my phone (circumventing the corporate firewall), it pushes fine.

Why is clone working with the custom certificate but not push? I want to get around this without using ssh.

3 Answers

Answers 1

Your company's firewall has installed a proxy which acts as man in the middle. To that end, it creates certificates for the sites you visit, e.g. github.com. These certificates obviously have a different issuer (your company's internal CA) which will not be trusted by the git client by default. Turning off sslVerify forces the git client to accept any certificate from any issuer. This is potentially dangerous. Your original approach, to add your company's CA to the list of issuers trusted by the git client, is IMHO the better way to allow your git client to talk to github.com from behind your company's firewall.

So why doesn't this setup let you push? What the other posters overlooked so far, is that the error in this case is not an SSL error. Only your client sees your company's certificate. If that is solved, it is solved. Github does not see this certificate. So any further tweaking with SSL settings will not help.

I could reproduce your case in so far as I could first see the SSL self-signed certificate problem which disappeared when I added the proxy's certificate to sslCAInfo. The bad news: I could not reproduce the authentication failed error. A push to github just worked. The good news: pushing to github from a setup similar to your's is possible.

If it is not a SSL problem, then it can only be caused by the proxy. Because the proxy presents its own certificate to the client, it is able to decrypt the SSL traffic and do a deep inspection of the data exchanged. The proxy does have the power to disable certain commands, to restrict access to specific sites or to strip username/password from requests.

Please talk to the IT security folks in your company. They should be able clarify whether the proxy imposes access restrictions for github or for certain git commands.

Answers 2

I am sure this could help you.

git config --global http.sslVerify false

As you may guess, this command changes ssl setting to disable ssl verification.

Answers 3

For testing disable temporally SSL for your repository with:

git config http.sslVerify false 

Then also check that your system clock is in sync since this can influence how SSL verification works, you may get something like:

[SSL certificate problem, verify that the CA cert is OK.  Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed]) 

Try to use ntp/chrony to synchronize your system clock.

Then to get the certificate you could use:

openssl s_client -showcerts -connect github.com:443 < /dev/null 

Get everything within -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- and create a cert.pem

Then use that file as you are trying in http.sslCAInfo:

git config http.sslCAInfo /path/to/cert.pem 

Once done try enabling back the http.sslVerify:

git config --unset http.sslVerify 
Read More

Create new git repository from a branch of another using libgit2?

Leave a Comment

In C++ using libgit2, I'd like to create a new local repository where its master branch is based on specific-branch from another local repository, maintaining its history so I can later synch between the two.

Essentially, I'm attempting the following, except using libgit2:

https://stackoverflow.com/a/9529847/1019385

So if I had files arranged as follows:

./old.git [branches: master, specific-branch]

./old/* [files and clone of ./old.git at specific-branch]

Where the commands would be something like:

git init --bare ./new.git cd ./old git push ./new.git +specific-branch:master 

And come up with something like (removed error checking to reduce code):

git_libgit2_init(); git_repository* repo = nullptr; git_repository_init(&repo, "./new.git", true); git_remote_create(&remote, repo, "origin", "./new.git"); git_remote_add_push(repo, "origin", "+specific-branch:master"); git_push_options optionsPush = GIT_PUSH_OPTIONS_INIT; git_remote_push(remote, nullptr, &optionsPush); 

What I'm not really sure is where to go from here and how to invoke git_remote_push() properly where it actually does something. This currently has no side effects, as ./old.git is not referenced. That is, ./new.git is created properly, but it doesn't contain contents of ./old.git/./old/*.

Help much appreciated.


Based on an answer suggesting a "fetch" approach, I've also attempted the following:

git_repository* repo = nullptr; if (git_repository_init(&repo, "./new.git", true)) {     FATAL(); } git_remote* remote; git_remote_create_anonymous(&remote, repo, "./old"); char* specs[] = { _strdup("specific-branch:master"), nullptr }; git_strarray refspecs; refspecs.count = 1; refspecs.strings = specs; if (git_remote_download(remote, &refspecs, NULL)) {     FATAL(); } 

This still has no effect.

2 Answers

Answers 1

In straight git the most flexible and direct method (as it doesn't require you to already have the entire repository you only want pieces of) is e.g.

git init --bare new.git; cd $_  git fetch --no-tags ~/src/git next:master    # to fetch and rename a branch # or git fetch ~/src/git v2.17.0; git branch master FETCH_HEAD   # full handroll 

To do this in libgit2, you can create a repository as usual with git_repository_init and an in-memory "anonymous" remote from a url (i'd hope a path would do as well, check that) with git_remote_create_anonymous, then git_remote_download the refspec you want from that.

Answers 2

It looks like you're creating a new repository, and then adding a remote on it and trying to use it to push to itself... If you want to truly emulate your commands, you'll need two repositories:

  1. git_repository_init the new.git, then
  2. git_repository_open the old, and then set up the remote on it, and push it to the new repository.

Something along the lines of:

git_repository *old = NULL, *new = NULL;  git_libgit2_init(); git_repository_init(&new, "./new.git", true); git_repository_free(new);  git_repository_open(&old, "./old"); git_remote_create(&remote, old, "origin", "./new.git"); git_remote_add_push(old, "origin", "+specific-branch:master"); git_remote_push(remote, NULL, NULL); git_repository_free(old); 
Read More

Friday, May 25, 2018

Git retagging sane and insane advice - Part 2

Leave a Comment

While I was reading about renaming of git tags , many people pointed to read this :

What should you do when you tag a wrong commit and you would want to re-tag?

If you never pushed anything out, just re-tag it. Use "-f" to replace the old one. And you’re done.

But if you have pushed things out (or others could just read your repository directly), then others will have already seen the old tag. In that case you can do one of two things:

The sane thing. Just admit you screwed up, and use a different name. Others have already seen one tag-name, and if you keep the same name, you may be in the situation that two people both have "version X", but they actually have different "X"'s. So just call it "X.1" and be done with it.

The insane thing. You really want to call the new version "X" too, even though others have already seen the old one. So just use git tag -f again, as if you hadn’t already published the old one.

However, Git does not (and it should not) change tags behind users back. So if somebody already got the old tag, doing a git pull on your tree shouldn’t just make them overwrite the old one.

If somebody got a release tag from you, you cannot just change the tag for them by updating your own one. This is a big security issue, in that people MUST be able to trust their tag-names. If you really want to do the insane thing, you need to just fess up to it, and tell people that you messed up.

Well, on retagging I asked an earlier question if you are interested - Git retagging sane and insane advice - Part 1 , however , it is not required. I have just chained the question as context is same.

So, my question is

I have 2 local repo of one remote - repo 1 and repo 2.

Step 1 : Create annotated tag in repo1 by name say X.

Step 2 : Push to remote.

Step 3 : Repo 2 pulls the tag.

Step 4 : Repo 1 deletes the Tag X and creates another tag X but with different message this time.

Step 5 : push to remote.

Step 6 : In repo2 , git pull --tags , updates the tag X.

How is this possible ? As highlighted above , git should not be doing this - that is updating tag ?

2 Answers

Answers 1

So if somebody already got the old tag,

That is your step 3.

shouldn’t just make them overwrite the old one.

Well it does not as it still holds old tag isn't it?

If somebody got a release tag from you, you cannot just change the tag for them by updating your own one.

So old one is in effect - everything is fine. You cannot change tag after pushing it.

Answers 2

It can be possible if your repo2 somehow configured to prune tags from the remote. For example there can be fetch.pruneTags=true in ~/.gitconfig or in some other place. If you want to figure it out run git config -l | grep fetch and look what it will print.

Prune tags is not default setting, so it is not reccomended to relay on that. You can use it on your controlled repos, but do not expect from other developers to have enabled prune-tags.

Detailed information is in the documentation:

Since keeping up-to-date with both branches and tags on the remote is a common use-case the --prune-tags option can be supplied along with --prune to prune local tags that don’t exist on the remote, and force-update those tags that differ. Tag pruning can also be enabled with fetch.pruneTags or remote..pruneTags in the config. See git-config.

The --prune-tags option is equivalent to having refs/tags/:refs/tags/ declared in the refspecs of the remote. This can lead to some seemingly strange interactions:

Read More

Thursday, May 17, 2018

error: cannot overwrite multiple values with a single value

Leave a Comment

I want to change my git mergetool kdiff3 to p4merge. because I'm getting an error on my windows system using kdiff3 mergetool.

/mingw32/libexec/git-core/git-mergetool--lib: line 128: C:\Program Files\KDiff3\kdiff3: cannot execute binary file: Exec format error application/config/constants.php seems unchanged.

So that I want to change to kdiff3 to p4merge, Here also I'm getting an error like

warning: merge.tool has multiple values error: cannot overwrite multiple values with a single value Use a regexp, --add or --replace-all to change merge.tool.

enter image description here

How can I solve this problem? Either kdiff3 or p4merge

1 Answers

Answers 1

It is possible your kdiff3 installation is broken since it is not working. Or maybe you tried to edit config file manually and messed its content. why? Because windows executables have .exe extension in general. you may try editing config again.

Anyways, that is not important anymore. This is what you need to use if you want to try any other tool.

git mergetool --tool=p4merge 

There are possibly others already installed with your git. You can see all of them in addition to compatible others.

git mergetool --tool-help 

Edit: This command works only if you set your path to the tool correctly. Otherwise, you always get No files need merging result. You already know how to set the path, but I will include here for anyone else that might need.

Get the list of configuration items:

git config -l 

See if you already have values set correctly, if any. then set to correct value or remove.

git config --unset mergetool.p4merge.path git config --add mergetool.p4merge.path "c:/somewhere/p4merge.exe" 
Read More

Thursday, April 19, 2018

How to verify that git exile works?

Leave a Comment

I try to use git exile. This is the sequence of actions that I usually take:

  1. Copy huge files to the repository (by that I replace the "old" content of the files by "new" content).
  2. git add (I guess that we do not copy the binary files to the "staging area" / "index" because the repository is "exile". Instead of that the "staging area" will get only a link to the "huge" content.)
  3. git exile push (I do not know what it does.)
  4. git commit

My expectation was that after this action, content of "huge" files will be copied to the drive and the original content of these files (in the local repository) will be replaced by a link to their location on the drive. However, for some reason I cannot verify it explicitly. I still have huge binary files in my repository (at least it is what I see with ls or du commands, or when I open the files with less).

Maybe my interpretation is wrong. Maybe the "links" exist only in the "staging area" and not in the "work-tree" / "file system".

What I basically want, is a switch between two states: (1) some files contain the original huge content, (2) file contain links to the huge content which is copied to the drive.

In other words, when I clone (or pull) the repository, I see "links" in some of the files (instead of the actual binary content). Then I replace these links by huge "binary content". Do the above described sequence of commands ("git add" + "git exile push" + "git commit") and, as a result, I still have the huge binaries in my working-tree. But now I want to push the local repository to the remote one and I do not want to push binary, I want to push new links. I pulled links and I want to push links. How can I achieve it?

1 Answers

Answers 1

Link 1 : The documentation on the git-exile github might be interesting:

https://github.com/patstam/git-exile

Link 2 : Check out this post for the mechanism:

What is the difference between "git push" and "git exile push"?

To maybe clear up some of the questions you had:

The replacement actually happens at git add time (See link 2)

When you use git exile push:

When you add files to git, git-exile stores the real content in the .git/exile folder and uses the data there to silently replace references with the real file contents when needed.

when you push:

This will look for exiled files in the current directory and all subdirectories, and push the objects corresponding to the current version to the remote repository.

You seemed to have more than one question, maybe with reference to the overall logic/understanding of git exile. I would suggest to look at those 2 links for the mechanism :) However, I hope this helps a little!

Read More

Tuesday, April 3, 2018

unable to access '/Users/dida/.config/git/attributes': Permission denied

Leave a Comment

When I do some git operations, such as 'git diff' or 'git add .', it shows that warning:

unable to access '/Users/dida/.config/git/attributes': Permission denied  

I wonder which config I did wrong and how can I fix it?
It's better with some commands, I am using mac command line

3 Answers

Answers 1

Cause

Git reads config settings from a variety of paths and the doesn't have access to some of them.

Git tries to read root config setting instead of config settings due to the starting script using su command with do not reset environment variables option (-m):

/bin/su -m $USER -c "cd $BASE/logs && $BASE/bin/startup.sh &> /dev/null" 

Bitbucket Server is being started as root with /etc/init.d/atlbitbucket start script. Since the init.d script calls start-bitbucket.sh which uses su -m this causes the environment variables for root to be preserved and atlbitbucket does not have permission to write in the root home directory.

Git was compiled from source using the default settings which prevents any users other than the one that compiled Git from running it

Resolution

Fix the permissions on the files and directories with regard to the Bitbucket Server user performing the command:

chown <USER>.<GROUP> -R /home/<USER>/.config chown <USER>.<GROUP> -R /home/<USER>/.gitconfig 

(info) Change the USER.GROUP by your username and group in your OS.

If Bitbucket Server starting script have su command, make sure that the option -m is not used.

If Bitbucket Server is being started with /etc/init.d/atlbitbucket start switch to starting Bitbucket Servering with service atlbitbucket start

To have Bitbucket Server automatically start at boot, run chkconfig atlbitbucket on

Recompile Git using more sensible defaults:

make prefix=/usr/local/git all make prefix=/usr/local/git install 

or maybe this articles could help you https://confluence.atlassian.com/bitbucketserverkb/permission-denied-on-git-config-file-779171763.html

Answers 2

Seems you've run sudo -H and sudo changed the ownership of some files to root. Take the files back:

sudo chown -R dida /Users/dida 

Answers 3

git uses the HOME and XDG_CONFIG_HOME environment settings to lookup the config files.

Make sure they are set properly, to your current user (check the result of the id command)

id -a 

Check also git config -l --show-origin to see where Git is trying to access those config files.

Read More

Wednesday, March 21, 2018

What is GIT_WORK_TREE, why have I never needed to set this ENV var, why now?

Leave a Comment

I'm using Git under Ubuntu Linux to sync and deploy my projects.

I have Repo on my local Linux working machine and two repos on my server, one bare repo and the one as a deployed app.

It always worked fine, but now I created another repo for my other website and now I get this error:

root@vserver5:/var/www/ninethsky# git pull origin master fatal: /usr/lib/git-core/git-pull cannot be used without a working tree. 

So I have to set a GIT_WORKING_TREE ENV-Var, but what is this exactly, where to set it?

This is my repo's .git/config:

[core]         repositoryformatversion = 0         filemode = true         bare = false         logallrefupdates = true [remote "origin"]         url = /home/git/ninethsky/.git         fetch = +refs/heads/*:refs/remotes/origin/* 

There is another repo with bare = true and a repo on my local working machine.

Then I removed all the repos, but the initial one, now I get:

root@vserver5:/var/www/ninethsky# git init fatal: GIT_WORK_TREE (or --work-tree=<directory>) not allowed without specifying GIT_DIR (or --git-dir=<directory>) root@vserver5:/var/www/ninethsky# git init --git-dir=/var/www/ninethsky error: unknown option `git-dir=/var/www/ninethsky' 

I solved the git init problem by unsetting GIT_WORK_TREE, which was set to blank. GIT_WORK_TREE and GIT_DIR are unset. git init works again, still there is a problem with git add . and so on when it comes to git actions in the cloned repo, which was set to bare.

Thanks, Joern.

2 Answers

Answers 1

If you have a non-bare git repository, there are two parts to it: the git directory and the working tree. The working tree has your checked out source code, with any changes you might have made. The git directory is normally called .git, and is in the top level of your working tree - this contains all the history of your project, configuration settings, pointers to branches, the index (staging area) and so on. Your git directory is the one that contains files and directories that look like a bit like this:

branches  description  HEAD   index  logs     ORIG_HEAD    refs config    FETCH_HEAD   hooks  info   objects  packed-refs 

While what I've described above is the default layout of a git repository, you can actually set any directories in the filesystem to be your git directory and working tree. You can change these directories from their defaults either with the --work-tree and --git-dir options to git or by using the GIT_DIR and GIT_WORK_TREE environment variables. Usually, however, you shouldn't need to set these.

The error that you see is from one of the first checks that git pull does - it must be run from a working tree. I assume that this is due to you having set the GIT_DIR or GIT_WORK_TREE environment variables. Otherwise, my best guess is that your .git directory is not accessible or corrupted in some way. If you list the contents of /var/www/ninethsky/.git, does it look like the listing I quoted above? Are all of those files and directories readable and writable by the user you're running the command as, or might they have had their permissions changed?


Update: In answer to the points in the additional information you updated your question with:

  • git init presumably fails because you still have the GIT_WORK_TREE environment variable set, and, as the error message says, if you're specifying the work tree, you also have to specify the git directory.
  • The second variant (git init --git-dir=/var/www/ninethsky) fails because the --git-dir should come before the init.

However, in this situation, you don't need to specify the work tree at all, 1 so I would make sure that you unset the GIT_WORK_TREE and GIT_DIR environment variables.

1 That said, it could be considered a bad idea to keep your .git directory under /var/www in case you accidentally set the permissions such that it is web accessible, so this might be an instance where you want to keep the git directory elsewhere - however, since these options are clearly already causing confusion for you, perhaps it's better to keep the git part simple and deny access to the .git directory with other means.

Answers 2

Perhaps it's better to keep the git part simple and deny access to the .git directory with other means.

You can use .htaccess to deny public access to the .git directory

Read More

Wednesday, February 7, 2018

How to checkout git repo subdirectory into current directory?

Leave a Comment

There is a remote repo with directory structure:

-directory1     -file1_1     -file1_2     ... -directory2     -file2_1     -file2_2     ... 

I have a folder on a web hosting with a custom name, say, "/path/public_html".

How do I set up git on the web hosting, so my "public_html" tracks a subdirectory "directory2" of a remote repo?

So, in other words, I want to execute some form of git command on the web hosting and update public_html to the latest content of "directory2". I don't care about pushing back to repo from web hosting, if it helps.

4 Answers

Answers 1

You cannot clone directly directory2 content, only directory2 and its content, meaning you always have a directory2/ folder on your disk.

If you want to see directory2 content in public_html (meaning not public_html/directory2/...), then you need a symlink.

That being said, you can still clone and checkout only directory2 folder, instead of cloning the full repo, as described in "Is it possible to do a sparse checkout without checking out the whole repository first?"

That is:

git init /a/path cd /a/path git config core.sparseCheckout true git remote add -f origin /url/remote/repo echo "directory2/" > .git/info/sparse-checkout git checkout [branchname] # ex: master 

That would give a a/path/directory2 folder, than your public_html can symlink to.

If having a directory2 folder in public_html does not bother you, then you could repeat the above commands in public_html instead of a/path.

Answers 2

how about cloning the entire repo on the host and use symlink between directories public_html -> directory2

Answers 3

This is straightforward git read-tree work. Make a bare git repo on the webserver, anywhere. Keep a manifest aka index for what's in your deployment directory and handle your updates with a pre-receive like so:

#!/bin/sh while read old new ref; do [[ $ref = refs/heads/deploy ]] && {     export GIT_INDEX_FILE=$GIT_DIR/deployment-manifest     export GIT_WORK_TREE=/path/public-html     git read-tree -um `git write-tree` $new:directory2 || exit 1 }; done 

Then push what you want deployed to the webserver's deploy branch, e.g. git push server master:deploy

Note that if some file being deployed this way has been changed in the deployment tree, the git read-tree here and the push will fail because git won't overwrite content you haven't told it about.

Answers 4

I don't care about pushing back to repo from web hosting

In this case you could use the archive command. Something like this:

git archive --remote=remote_repo --format=tar branch_name  path/to/directory2 > /path/public_html/dir2.tar && cd /path/public_html && tar xvf dir2.tar 
Read More

Saturday, January 27, 2018

Can I cache git credentials on a per-project basis?

Leave a Comment

Several people are working on several projects on a single webserver via a network share. Each project has their own git repository. When starting a project, we have a personal development environment per developer working on the project and a staging environment for each project. All files are owned by www-data, because this is the user that Apache uses.

To prevent us from having to type our username and password several times when pulling, pushing and switching to a new branch, we are currently using the credential cache (as found here).

$ git config --global credential.helper cache --timeout=900 

The problem we are facing is that when someone (user 1) performs an authenticated git action, they enter their credentials. Within the timeout, someone else (user 2) performs an authenticated git action in their own repository, which uses the credentials of user 1. This will cause one of two things to happen:

  • User 2 gets an error that the repository does not exist. This is because user 1 does not have the rights to perform actions on the repository of user 2.
  • User 2 pushes a commit (with them as author), using the account of user 1. The push shows up in the history of user 1.

I think this issue can be partly mitigated by adding the username to the git repository url (e.g. username@git.domain.ext/repo/name.git), but this only works in the beginning stages where we have personal development environments per user. The staging environment needs to be accessed by multiple people, so we cant hardcode the username. After we have done initial development and the project has gone live, we clean up development environments, because we don't have infinite space. If we need to make changes after we have cleaned up personal development environments, we usually use the staging environment to do so, which would cause the same issue to happen.

The git config --global credential.helper command causes the credentials to be stored server-wide. Lowering the timeout only helps so much. Can we cache credentials per development environment instead?

4 Answers

Answers 1

I couldn't find an option to match exactly what you're after, so I wrote one: a git credential helper that stores credentials on a per-shell basis.

It sets up a temporary encryption key and a temporary directory for data on login, uses them to store the username and password given by git in the store phase of the credential helper process, then gives them back in the get phase.

Caveats:

  1. I've tested it but only in a fairly limited way. It works: two separate login shells for the same user can have separate cached credentials.
  2. It's fairly naive: it ignores any username and repo URL given by git when storing and retrieving credentials.
  3. It will leave behind a temp directory with a few small files for every login.
  4. It stores credentials encrypted, but I make no claims about how secure this is in practice.
  5. It requires Python 3.6, pycrypto, and bash; I've tested it on linux and macOS. It should be fairly easy to adapt for other setups.

Open an issue if you run into any trouble and I'll see what I can do.

Answers 2

One mitigating solution I have seen in that kind of shared environment is to have a wrapper shell script named 'git' which will:

  • overshadow the actual git command
  • be launched by a dedicated account (through sudo -u xxx)
  • read credentials from a temp file named after the ps id (file owned by xxx, not readable by the original user)
  • if that temp file does not exist (on the first git call), creates it and store username/password.
  • use that "store" helper for pull/push/clone commands, with a command-local config /usr/bin/git -c credential.helper 'store --file=/path/to/temp/credentials' ..., again executed by the wrapper as xxx.

That same script can not only ask for credential, but also ask for the authorname/email, and add that to its git command, settings local GIT_AUTHOR_NAME/EMAIL for each /usr/bin/git calls.

The idea is to do git command with local configs (local to the git command itself)

Answers 3

Here are two possible solutions to your problem:

1 - have one OS user per developer.

This is the cleaner option: Each of the developers would connect to a different user account. Add these users to the group www-data and set the file options accordingly: allow read and write by the group members.

Each users's authentication will then be managed independently.

2 - store the configuration per project

Currently, the --global storage of user credentials is done at OS user level. Instead, you may use --local, in order to store the credentials at project level.

This will solve the described problem between users 1 and 2. However, you still may lack some traceability working this way: in case two developers work on the same project, if user2 pushes some changes shortly after user1, user1's authentication details will be used, and it will look like she is the person who did the push - whereas it's user2.

Read git config --help for detailed information about the --local option and data storage locations.

Answers 4

Stop using the network share. Have users clone the repository on their own machines and do changes that way. No files should be changed directly in staging environment, not even through network shares.

Users can have local Apache installations if they want to see their changes immediately and experiment based on that.

In addition, you could consider hosting your repositories in a separate server and do deployments from those repositories to your staging environment using a deployment tool, as git is not really a deployment tool. This could be automated. However, the biggest thing you should do is to stop using the network share and use git push to initiate the changes instead of changing files on the server yourself.

Read More

Wednesday, January 17, 2018

Squash and merge master into same branch

Leave a Comment

Is there a way to squash and merge master into the same branch? Effectively taking all the pending commits and putting them into 1 commit?

My original idea is a script that takes my-branch and does a git checkout master && git pull && git checkout my-branch-squashed and then git merge --squash my-branch (deal with any merge conflicts) and then finally delete my-branch and rename my-branch-squash to my-branch

This seem very round-about and possibly bad, so I am trying to see if there is any other way. The intent I am trying to solve is that when I put branches on github and they are "squashed and merged" into master, the branch that exists on the local machine doesn't match the branch that was merged into master, so when using git branch --merged ${1-master} | grep -v " ${1-master}$" | xargs -r git branch -d; it doesnt correctly delete the branches that have already been merged into master. What I want is a way to auto-delete old branches that have been merged into master

3 Answers

Answers 1

You can do that using git rebase, and fixup the commits you want to merge:

$ git rebase -i HEAD~5  pick c2e2c87 commit 1 f 689d474 commit 2 f aa9d9b4 commit 3 f 888a009 commit 4 f d396e75 commit 5  # Rebase 2f7f53e..d396e75 onto 2f7f53e (5 commands) # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # d, drop = remove commit # # These lines can be re-ordered; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. # # However, if you remove everything, the rebase will be aborted. # # Note that empty commits are commented out 

You can use git rebase -i --root in order to rebase from the first commit.

Answers 2

If all you really want is to squash your local development history before submitting a pull-request, the simplest way is to just develop on a local feature branch which is different from whatever upstream branch you want to affect.

Then, the procedure for squashing it onto master is

git checkout master git merge --squash feature 

(replace master with integration or whatever).

I'd use rebase -i for fine control, but for this simple case we can use git's knowledge of your history to figure out the last common ancestor automatically.

Answers 3

Setting aside the issues with the merge-squash workflow, which have already been discussed thoroughly in many places, in light of workflows often being out of your control.

There is a method you can use and though it is not 100% effective, it does have a fairly good track record in my experience and always fails safe.

Without ancestry to rely on, you need is a way of determining if two snapshots are identical. You can use the hash of the commits' trees with this command:

git show --format="%T" <committish> 

In order to check if a branch can be deleted, first merge master into your branch. If there is a conflict in this merge, or there was a conflict in the original squash, you won't be able to use this method (this is the less than 100% effective part).

Thanks to the nature of git, it does not matter what order a set of patches are applied if no conflicts occur. So if the result of this merge should be identical to the head of master if your branch has been merged. This can be confirmed by comparing the tree hashes of the two branch heads you can find out if any unmerged code exists on your branch.

This could be boiled down into an command for single use that can be easily aliased like:

if [ $(git show --format="%T" origin/master) = $(git show --format="%T" HEAD) ]; then echo Merged; else echo Unmerged; fi 

Or built into a shell script that will loop through all your local branches, merge them, test them, and delete the ones that have been merged.

All that being said, using interactive rebase to flatten your branch and getting the maintainer to use a fast forward only merge strategy on the pull requests would make all this unnecessary.

Read More

Monday, December 4, 2017

How to search a block of code as a whole

Leave a Comment

My files has

.settings { }   .field {     margin-bottom: 1em; } 

I want to know when

.settings { } 

was formed.

I know if I want to search one line of code, I do git log -S".settings {".

But here I want to search

.settings { } 

as a whole, I tried

git log -S".settings {\r}" confirm.less.css git log -S".settings {\n}" confirm.less.css git log -S".settings {\r\n}" confirm.less.css 

but all retrun nothing.

How do I search a block of code as a whole containg new line characters?

2 Answers

Answers 1

Try

git log -L '/^.settings {/,+1':path/to/it 

That'll get you the whole history of updates to that range, but the oldest of them will be what you want.

Answers 2

There was a few issues getting this to work properly.

First, I think you need to handle the { } metacharacters in your RegEx by escaping them, and enable extended matching with --pickaxe-regex. I also used a simple \s* to greedily match any space including newlines between brackets.

Here is the resulting command that I came up with

git log -S".settings \{\s*\}" --pickaxe-regex confirm.less.css

Which returned the commit containing the first appearance.

Read More

Thursday, October 19, 2017

Git merge master into orphan without commit history

Leave a Comment

Given an orphan branch without history, how would I incorporate changes done on master branch, since the moment of creation of the orphan, without copying all commits history when pushing the orphan remotely.

A <- B <- C <- D            orphan(created from state B) <-X <- Y 

I would like to bring c and d to the orphan branch and then x and y to master.

If I do checkout orphan, merge master or rebase master orphan gets the commits, but also all history tree. such as when I push orphan to a remote server, everybody will be able to see all master's history as well.

Also later I would like to merge orphan back into master, bringing commits x and y there.

Edit:

Now merging orphan into master works ok with git merge

A <- B <- C <- D <------X <- Y                        /           orphan <-X <- Y  

But, merging master back into orphan either puts the entire master history into orphan (such as becomes X preceded by B) or with cherry picking, but than I need to skip the merge-commits and also get a lot more conflicts

3 Answers

Answers 1

Grafts are built for exactly this.

root=$(git rev-list my-orphan-branch --max-parents=0)  # get the orphaned-branch root echo $(git rev-parse $root B) >.git/info/grafts        # locally remember its real parent 

and now all the local commands will know about the ancestry but it will remain repo-local, push and fetch won't export it.

Answers 2

Based on the comments and what you are intending, I'm going to suggest an alternate workflow/design to avoid the need to do super-ordinary Git things.

It sounds like there are some special config files or settings with passwords or similar sensitive information that you don't want to pass back to the remote, that are baked into your compiled files in the repo. Why not separate those out from the baked in code? If these files are already separate, then you can just .gitignore them. Regardless, it's better to have both a standard default that is compiled in or a default config file that gets distributed with the repo (and/or the application itself), and then have the code check for the presence of a custom config file, which is saved outside the repo or ignored with .gitignore.

Without knowing more about your setup (linux/PC/Mac, programming language, frameworks, etc.) it's difficult to give further guidance - for example, with Visual Studio development for C#, there is a Properties.Settings file that can be setup. The defaults become a part of the compiled code, but a class gets auto-generated that will save out any changes to a user-specific file and reload it when the application launches, but this is in the user home directory, and not in the development folders. Another method would be having the file locally, and using .gitignore to have Git not transfer it between repos.

I think this method will be better for you long-term, though might incur a short-term cost to update your design for better config management. My concern is that if you need some non-standard Git wizardry every time you need to push changes will cause times where someone forgets to take the extra steps and pushes the sensitive info up to the remote.

Answers 3

Try this:

git checkout orphan git merge --no-commit --squash master git commit 
Read More

Wednesday, October 11, 2017

Configuring GitLab to use SAML OmniAuth with an Active Directory IdP

Leave a Comment

I am in the process of altering an existing GitLab installation to use SAML rather than LDAP for authentication.

At this point, users can successfully sign into the Web application using the 'Sign in with Saml' button. I am unclear, however, about what seems to be a difference between the LDAP and SAML approaches: users with accounts created via an LDAP sign-in can then access Git repositories (e.g. using clone, push, ...) using their LDAP usernames and passwords, but users with accounts created via a SAML sign-in cannot.

Through experimentation, I’ve found that users can access the Git repositories if they use the GitLab UI to set a separate GitLab account password on the account that is created during the initial SAML interaction. I was pointed in this direction by a GitLab message that appeared after creating a project under one of the new user accounts: 'You won't be able to pull or push project code via HTTPS until you set a password on your account'.

It seems possible that this separate password configuration is only necessary because I’ve misconfigured the SAML integration somehow. So, my question is whether I am wrong to expect that authenticating access to the GitLab-hosted Git repositories would work the same regardless of whether SAML or LDAP is used? If not, does anyone know of relevant SAML configuration settings that I should review?

In case it’s of interest: I have posted a similar question to the GitLab Google group, but I have not received any responses there yet.

0 Answers

Read More

Tuesday, September 12, 2017

WebStorm keeps crashing my locally ran server because of Git's index.lock

Leave a Comment
Error: EPERM: operation not permitted, lstat 'C:\ProjectDirectory\.git\index.lock'     at Error (native) 

I'm using WebStorm and everytime I run the local server for testing purposes using npm start, it crashes inevitably sometimes after doing nothing, and sometimes after making a change or so.

I'm using this React boilerplate and the actual author responded to a bug issue I brought up about this saying "Based on the error, it looks like either your editor or your source control system is locking files."

I'm a bit tired restarting the server every time I make a couple changes and would love to fix this.

Full error log

1 Answers

Answers 1

Only IDE have reason to watch .git/ folder. So if something else tries then it's a bug in configuration.

npm start is an alias for npm-run-all --parallel test:watch open:src lint:watch.

Make sure that .git/ is exempted in their configuration.

Read More

Sunday, September 10, 2017

jenkins ignores “inclusive regions”

Leave a Comment

I have two jenkins projects

1) one that polls over git repo

2) second that triggers java application

I want to configure (1) to poll on a specific file only, so i did it under "inclusive regions". However, i see the project is triggered after every change in the repo, not only when the specific file is changed.

Has anyone experienced the same?

Other work around?

enter image description here

1 Answers

Answers 1

Following the question "Jenkins Git plugin included regions not working", make sure that:

  • your "included region" is a path relative to the root folder of your Git repo.

    a/b/c...bal/sdk.conf 
  • "Force polling using workspace" under "Source-Code-Management - Additional Behaviours"

Note: there are still open bugs relative to "included regions":

Make sure you are not monitoring all branches.

Read More