1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/*
 * Copyright (C) 2021  Aravinth Manivannan <realaravinth@batsense.net>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
use git2::{build::CheckoutBuilder, BranchType, Direction, ObjectType, Repository};
use log::info;
use serde::Deserialize;

#[derive(Debug, Clone, Deserialize)]
pub struct Page {
    pub secret: String,
    pub repo: String,
    pub path: String,
    pub branch: String,
}

impl Page {
    pub fn create_repo(&self) -> Repository {
        let repo = Repository::open(&self.path);

        let repo = if repo.is_err() {
            info!("Cloning repository {} at {}", self.repo, self.path);
            Repository::clone(&self.repo, &self.path).unwrap()
        } else {
            repo.unwrap()
        };
        //        let branch = repo.find_branch(&self.branch, BranchType::Local).unwrap();

        //repo.branches(BranchType::Local).unwrap().find(|b| b.unwrap().na
        {
            let repo = Repository::open(&self.path).unwrap();
            self._fetch_upstream(&repo, &self.branch);
            let branch = repo
                .find_branch(&format!("origin/{}", &self.branch), BranchType::Remote)
                .unwrap();

            let mut checkout_options = CheckoutBuilder::new();
            checkout_options.force();

            let tree = branch.get().peel(ObjectType::Tree).unwrap();

            repo.checkout_tree(&tree, Some(&mut checkout_options))
                .unwrap();
            //                repo.set_head(&format!("refs/heads/{}", &self.branch))
            //                    .unwrap();

            repo.set_head(branch.get().name().unwrap()).unwrap();
            //           }
        }
        repo
    }

    fn _fetch_upstream(&self, repo: &Repository, branch: &str) {
        let mut remote = repo.find_remote("origin").unwrap();
        remote.connect(Direction::Fetch).unwrap();
        info!("Updating repository {}", self.repo);
        remote.fetch(&[branch], None, None).unwrap();
        remote.disconnect().unwrap();
    }

    pub fn fetch_upstream(&self, branch: &str) {
        let repo = self.create_repo();
        self._fetch_upstream(&repo, branch);
    }
}