How to retrieve default repository branch using gitpython? - gitpython

While I do know how to get the current active branch, I do want to retrieve the default repository branch (as in master or main) using gitpython and I was not able to find any docs on that (even pdb was of not much help).
import git
repo = git.Repo(".", search_parent_directories=True)
repo.active_branch # <-- that is current branch

Related

Github how to push Xcode project without old files and folders?

I finished an Xcode project and pushed it to github from Xcode 'Source Control' Menu. Then I changed the project name CountryBook to Countries. I Built project and ran. Everything was okay. Then I coiped project folder to desktop as a backup. Then pushed project again. Everything has messed up. Some old named folders and files still exist in repo. Then I deleted every directory and file from github repository. Now, backup version of project is working. But when I try to push it to repo, old files are still exist. I deleted 'origin' from 'Remotes' and created a new repo named 'Countries'. I pushed project again but it was same. A mixed version of old files and new files. When I clone the github version of project, of course it is not runnable. What sould I do and how can I push clean version of my project? I don't want to lose project.
This is Countries repo now:
This is my working project folder with correct content:
I would fix it via command line, lets assume you start from scratch:
Step 1 - prepare the working branch:
Clone the project
Navigate to root folder of the project
Checkout the main branch ("main", "master", or whatever it is)
Create a new branch you will be working with
git clone https://github.com/yourorg/yourrepo
cd yourrepo
git checkout main # or master
git checkout -b fixprojectstructure # branch name can be anything
Step 2 - clean project locally
Delete old project, old workspace, ensure the names in Podfile and Podfile.lock are fine
Build the project and ensure it's working
Step 3 - commit your changes:
# assuming you are in the root of the project
git add .
git commit -m "Some explanation"
Step 4 - push your changes:
I usually do it the lazy way: just run git push, which will show you the proper syntax to push remotely, something like
> git push
fatal: The current branch fixprojectstructure has no upstream branch.
To push the current branch and set the remote as upstream, use
git push --set-upstream origin fixprojectstructure
> git push --set-upstream origin fixprojectstructure
Enumerating objects: ...
...
remote: Create a pull request for 'fixprojectstructure' on GitHub by visiting:
remote: https://github.com/.../pull/new/fixprojectstructure
remote:
...
Branch 'fixprojectstructure' set up to track remote branch 'fixprojectstructure' from 'origin'.
Step 5 - merge your changes:
Basically just do what the line above is saying:
Navigate to https://github.com/.../pull/new/fixprojectstructure
Create pull request
Merge pull request to main (or whatever the initial branch was)
Note on the side: configure the gitignore file properly for your repo as well. For starters, follow the gitignore template to create a proper gitignore file, and then change it the way you need to.
For instance:
Usually, if you use cocoapods, you do not store .workspace folder and its contents in the repo. Instead it's generated using pod install command on each machine that needs it.
It's also common to exclude Pods directory from storing in the repo, although there are pro / cons arguments both ways.

How to import a specific branch of forked repo into Go code

I faced with the following problem:
I forked a repo, and made some modifications to it under new branch
I create PR to upstream repo and it is not yet merged
I want to adjust my Go codebase to import the specific branch of my forked repo
The problem:
if the original repo is github.com/user/pkg/v3 then the forked repo appears as github.com/myusername/pkg
moreover, I made a new branch, e.g. mybranch where I made my fixes
in the code where I used original repo I have an entry in my go.mod file as github.com/user/pkg/v3 which I want to replace with specific branch of my forked repo
How should I correctly solve this issue?
What I see when I tried to change go.mod of my forked repo to be github.com/myusername/pkg/v3 and then call go get github.com/myusername/pkg#mybranch is the following
go: github.com/myusername/pkg/v3#vxx-xx-xx: parsing go.mod:
module declares its path as: github.com/user/pkg/v3
but was required as: github.com/myusername/pkg/v3
I found required solution. The trick was to perform the following series of steps:
fork original repo
create new branch
add modifications to the code
push branch into forked repo
tag this branch with version higher then original repo, e.g. if original repo had v3.1.1 then the tag I applied to my forked branch was v3.1.2
go to code which depends on this package
change go.mod file of my package to use replace directive and my new tag like this
replace github.com/user/pkg/v3 => github.com/myusername/pkg/v3 v3.1.2
Therefore, in order to use forked repo with new branch we must tag this branch in forked repo with version higher of the tag in upstream repo.

GitPython get list of commits from a repo-branch

I have a Git repository URL and a branch name.
Using GitPython how do I get all the commits from the branch?
From https://gitpython.readthedocs.io/en/stable/tutorial.html
Meet the Repo type
The first step is to create a git.Repo object to represent your repository.
from git import Repo
# rorepo is a Repo instance pointing to the git-python repository.
# For all you know, the first argument to Repo is a path to the repository
# you want to work with
repo = Repo(self.rorepo.working_tree_dir)
assert not repo.bare
In the above example, the directory self.rorepo.working_tree_dir equals /Users/mtrier/Development/git-python and is my working repository which contains the .git directory. You can also initialize GitPython with a bare repository.
...
...
The Commit object
Commit objects contain information about a specific commit. Obtain commits using references as done in Examining References or as follows.
Obtain commits at the specified revision
repo.commit('master')
repo.commit('v0.8.1')
repo.commit('HEAD~10')
...
I would suggest reading the tutorial I quoted and at least the entire The Commit Object section of it. (https://gitpython.readthedocs.io/en/stable/tutorial.html#the-commit-object)
(Sorry for bad formatting, for some reason stackoverflow didn't let me make it a quote block)

Reinitializing a git repository

I have an xcode project on my desktop in a directory that originally had a git repository with a tracking branch that tracked a remote branch on github. The remote branch has some 84 commits and is 2 commits ahead of the master branch of the project I'm adding features to. I changed the name of the folder/directory on my desktop. I'm not 100% sure if this is the reason why but when I go to git status I get: fatal: Not a git repository (or any of the parent directories): .git. My plan is to simply git Init, add the remote branch and create a new tracking branch and than commit locally to that branch and than push to the remote branch. However, I'm a git beginner and I'm not sure if this is the proper way to go about it. I'm very weary of losing any commit history or accidentally breaking something. Is the method I outlined a good way of rectifying this loss of the git repo?
If you have all your code updated in remote repo then your local .git is deleted. You don't need to re-init your local repo. Rather just clone it.
git clone remote_repo
If you don't have any commit in remote repo, Simply follow
git init
git add all_local_files
If you have updated remote repo than some commits made in local but not pushed and you lost .git. Simply clone remote. Add all files in a single commit
git clone
git add all_local_files
Looks like you messed up your git repository, but not the code / contents.
One way to restore and keep local changes ( if any ) would be:
Clone another copy of your repo from github.
Copy all modified files to the new repo, omitting removed ones: rsync -duztv /old/local/repo/ /new/local/repo
git status to see what the situation is.

Working with multiple Git

I have following dir stucture
root
root/framework (Yii)
root/protected/messages
All of this folder must be separate git repos
What I want to do is
root and root/framework must be separate repos. But
root/framework must be pull only because I have no push access to this repository. I mean I want to pull yii when I pull parent repo, but don't want to push when I push parent repo.
Another problem is, remote dir structure of Yii (root/framework) looks like http://screencast.com/t/mU1TgXuZDv
I need only framework folder's contents. How can I pull only this folder's contents into root/framework ?
To make root/protected/messages separate git repo so that, when I push & pull root git repo, to do it for this one too. In other words, to push & pull with parent one to 2 separate remotes.
To solve second problem, I initialized new repo inside root/protected/messages but now they push & pull separatelly. I mean, I want them to push & pull changes to/from 2 remotes at once. Can't figure out how to do it.
Also I have no idea about first problem.
Any suggestions?
In order to create a separate and independent git repos within a parent git repo, you want to look into Git Submodules (http://git-scm.com/book/en/Git-Tools-Submodules). These basically allow you to create a completely independent git repos inside a directory which by itself is a git repository.
To create the submodule the command is git submodule add git://path/to/gitname.git folder-containing-the-inner-git. Of course you will need to cd into the parent folder before firing this command, which in your case will be root. The git://path/to/gitname.git will be the git url for Yii and folder-containing-the-inner-git will be root/framework.
In order to pull a specific folder of Yii of the entire git repo you might want to try out git checkout as suggested by this question on stackoverflow How to pull specific directory with git. I have never tried this myself.
Also, as of Git 1.7 you can also do a sparse checkout (https://www.kernel.org/pub/software/scm/git/docs/v1.7.0/git-read-tree.html#_sparse_checkout). Although you will still have to fetch the entire repo.
Once you create a separate git repo using git submodules inside root, you will have to push and pull the git inside root/protected/messages seperately. You can however automate this process by creating a git hook (http://git-scm.com/book/en/Customizing-Git-Git-Hooks) for the repo inside root. A hook is a script that can be executed upon specific git events/operations like committing, merging, etc. For a full list of these events you can refer to this page ... http://www.manpagez.com/man/5/githooks/
It seems that there is no event for a git push or pull. However there is an event for git merge ... post-merge :
This hook is invoked by git merge, which happens when a git pull is
done on a local repository. The hook takes a single parameter, a status
flag specifying whether or not the merge being done was a squash merge.
This hook cannot affect the outcome of git merge and is not executed,
if the merge failed due to conflicts.
This hook can be used in conjunction with a corresponding pre-commit
hook to save and restore any form of metadata associated with the
working tree (eg: permissions/ownership, ACLS, etc). See
contrib/hooks/setgitperms.perl for an example of how to do this.
So you can write a simple bash script like :
cd root/protected/messages
git pull origin master
So everytime you pull from the outer repo in root this script will get fired and you will be able to pull the contents of your inner repo as well. However, this will happen on every merge, not just the merges that happen on a pull so you might want to be careful.
Hope this helps.
You may try more straightforward way:
Init your git repo in root;
Add your root/framework to .gitignore in it;
Go to root/framework and init new git repository there;
You will have matroshka styled repos. But, to be frankly, they will be harder to support than git-submodules solution, since root repo does not aware about other repos at all, and all pushesh, pulls need to be done separately inn each repo.

Resources