Folders and files
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Repository files navigation
#+TITLE: treebundel [[https://melpa.org/#/treebundel][file:https://melpa.org/packages/treebundel-badge.svg]] This package is used for bundling related git-worktrees from multiple repositories together. It's a bit of an opinionated workflow on how to manage and organize your projects. It helps switch quickly between feature-related projects and ensure you're on the branch related to that feature. When you're done with your changes, you can use the projects in the workspace and know which ones were modified to simplify the process of getting the changes merged in together. Additionally, git metadata (the =.git= directory) is shared between all projects. You can stash, pop, and pull changes in from the same repository in other workspaces thanks to the power of [[https://git-scm.com/docs/git-worktree][git-worktrees]]. * Contents :PROPERTIES: :TOC: :include siblings :depth 0 :force ((nothing)) :ignore (this) :local (nothing) :END: :CONTENTS: - [[#terminology][Terminology]] - [[#installation][Installation]] - [[#usage][Usage]] - [[#configuration][Configuration]] - [[#nifty-snippets][Nifty snippets]] - [[#license][License]] :END: * Terminology | Term | Description | |-------------+--------------------------------------------------------------------------| | *Bare* | A bare repository used as a source to create a *project*'s git-worktree. | | *Project* | A git-worktree checked out from a *bare* stored in a *workspace*. | | *Workspace* | A collection of *project*'s created from *bare*'s. | | *Prefix* | An string used to generated a default branch name for new projects. | The main workspace directory contains workspaces which each contains a collection of projects: #+BEGIN_SRC treebundel-workspace-root (default: "~/workspaces/") | L workspace1 | L project-one (branch: "feature/workspace1") | L project-two (branch: "feature/workspace1") | L project-three (branch: "feature/workspace1") | L workspace2 L project-one (branch: "feature/workspace2") L project-two (branch: "feature/workspace2") L project-three (branch: "feature/workspace2") #+END_SRC * Installation This package is available on [[https://melpa.org/][MELPA]]. ** use-package #+BEGIN_SRC emacs-lisp :results none (use-package treebundel :ensure t) #+END_SRC ** straight.el Or you can install from source. Straight example: #+BEGIN_SRC emacs-lisp :results none (straight-use-package '(treebundel :type git :host github :repo "purplg/treebundel")) ;; -- Configuration goes here -- #+END_SRC * Usage The main commands for using treebundel. - treebundel-open :: Open a project in a workspace. - treebundel-open-project :: Open other project within current workspace. If you're already in a workspace, prompt to open a different project within that workspace. - treebundel-add-project :: Add a project to a workspace. Will prompt you for a bare repository to add to your workspace. - treebundel-remove-project :: Remove a project from a workspace. The project must not have any uncommitted changes for it to be removed. - treebundel-delete-workspace :: Delete a workspace. Any projects within the workspace are checked to see if they're clean, and if so, all projects and the workspace itself are deleted. Anything committed is still saved in the respective projects' bare repository. Assuming default configuration, the following steps will create a bare clone of the provided repo URL to =~/workspaces/.bare/<repo-name>.git=, then create and open a worktree for a new branch called =feature/<workspace-name>=. 1. Interactively call ~treebundel-add-project~. 2. Enter name for the new (or existing) workspace. 3. Select =[ clone ]=. 4. Enter the URL to clone for the repository to be added to the workspace. 5. Specify the name of the branch to checkout. By default, it'll pre-fill with <treebundel-branch-prefix>/<workspace-name>. You can also select an existing branch. 6. Specify the project name which will be the name of the worktree is created in. You should then be prompted with your ~project-switch-project~ prompt to begin editing. Whenever you need a different repository, you can call ~treebundel-open-project~ to open and adjacent project in your current workspace or ~treebundel-open~ to open a project in a different workspace. * Configuration - treebundel-workspace-root :: *Default*: =“~/workspaces/”= The most important variable you probably want to configure is ~treebundel-workspace-root~. This configures where all of the treebundel workspaces are going to be located on your file system. - treebundel-project-open-function :: *Default*: =#'project-switch-project= This is the function called when a project is opened. You could also just make this ~find-file~ to just open the file instantly or any other function that takes a file path. - treebundel-fetch-on-add :: *Default*: =nil= Set to nil to disable the automatic ~git fetch~ when adding a project. When disabled, you may not be able to see new branches on remote without manually do a git fetch. You can interactively call the ~(treebundel-fetch-bare)~ command to manually update a repository. - treebundel-bare-dir :: *Default*: =(file-name-concat treebundel-workspace-root “.bare”)= This is the directory that bare repository get cloned to. The intent is for this to be mostly transparent, hence the =.= prefix to make it hidden by default. - treebundel-branch-prefix :: *Default*: =“feature/”= A string used to generate a default branch name created with treebundel. By default, it's =feature/= such that when you add a new project to a workspace, the new branch is name =feature/<workspace-name>=. You don't have to use this name, it's just pre-populated for convience. You can use dir-locals to set workspace-specific prefixes although this, unfortunately, prevents you from using dir-locals in your project since dir-locals only looks as the closest file. ** Hooks - ~treebundel-before-workspace-open-functions~ - ~treebundel-before-project-open-functions~ - ~treebundel-after-project-open-hook~ - ~treebundel-after-workspace-open-hook~ These hooks are called before or after a project or workspace is opened. =treebundel-before-workspace-open-functions= receives the name of the workspace to be opened as a single argument and =treebundel-before-project-open-functions= receives the workspace and project name opened. See the [[#project-tabs][Project Tabs]] example to see an example on how to use =treebundel-before-project-open-functions= to create a new tab for every project. * Nifty snippets This snippets can extend the usefulness of treebundel. ** Project Tabs To create a new tab for every project opened with treebundel: #+BEGIN_SRC emacs-lisp (add-hook 'treebundel-before-project-open-functions (lambda (workspace project) (tab-bar-select-tab-by-name (format "%s/%s" workspace-name project-name)))) #+END_SRC ** Workspace Notes This snippet will open a file within a =projects= directory in your =org-directory= an org file with the name of your workspace. #+BEGIN_SRC emacs-lisp (defun my/open-project-notes () (interactive) (if-let ((workspace (or (treebundel-current-workspace) (treebundel-read-workspace)))) (find-file-other-window ;; e.g. ~/.org/projects/some-feature.org (file-name-concat org-directory "projects" (file-name-with-extension workspace "org"))) (user-error "Not in a workspace"))) #+END_SRC * License MIT